154d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu/*
254d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu * Copyright (C) 2012 The Android Open Source Project
354d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu *
454d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu * Licensed under the Apache License, Version 2.0 (the "License");
554d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu * you may not use this file except in compliance with the License.
654d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu * You may obtain a copy of the License at
754d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu *
854d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu *      http://www.apache.org/licenses/LICENSE-2.0
954d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu *
1054d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu * Unless required by applicable law or agreed to in writing, software
1154d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu * distributed under the License is distributed on an "AS IS" BASIS,
1254d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1354d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu * See the License for the specific language governing permissions and
1454d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu * limitations under the License.
1554d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu */
1654d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu
1754d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liupackage com.android.camera.ui;
1854d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu
1954d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liuimport java.util.Locale;
2054d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu
2154d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liuimport android.content.Context;
2254d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liuimport android.media.AudioManager;
2354d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liuimport android.media.SoundPool;
2454d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liuimport android.os.Handler;
2554d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liuimport android.os.Message;
2654d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liuimport android.util.AttributeSet;
2754d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liuimport android.util.Log;
2854d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liuimport android.view.View;
2954d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liuimport android.view.animation.Animation;
3054d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liuimport android.view.animation.AnimationUtils;
3154d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liuimport android.widget.FrameLayout;
3254d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liuimport android.widget.TextView;
3354d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu
3454d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liuimport com.android.camera.R;
3554d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu
3654d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liupublic class CountDownView extends FrameLayout {
3754d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu
3854d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    private static final String TAG = "CAM_CountDownView";
3954d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    private static final int SET_TIMER_TEXT = 1;
4054d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    private TextView mRemainingSecondsView;
4154d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    private int mRemainingSecs = 0;
4254d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    private OnCountDownFinishedListener mListener;
4354d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    private Animation mCountDownAnim;
4454d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    private SoundPool mSoundPool;
4554d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    private int mBeepTwice;
4654d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    private int mBeepOnce;
478e3b1df4fcc770965d0796ac2046ef9e265d4bdbDoris Liu    private boolean mPlaySound;
4854d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    private final Handler mHandler = new MainHandler();
4954d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu
5054d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    public CountDownView(Context context, AttributeSet attrs) {
5154d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        super(context, attrs);
5254d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        mCountDownAnim = AnimationUtils.loadAnimation(context, R.anim.count_down_exit);
5354d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        // Load the beeps
5454d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        mSoundPool = new SoundPool(1, AudioManager.STREAM_NOTIFICATION, 0);
5554d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        mBeepOnce = mSoundPool.load(context, R.raw.beep_once, 1);
5654d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        mBeepTwice = mSoundPool.load(context, R.raw.beep_twice, 1);
5754d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    }
5854d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu
5954d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    public boolean isCountingDown() {
6054d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        return mRemainingSecs > 0;
6154d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    };
6254d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu
6354d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    public interface OnCountDownFinishedListener {
6454d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        public void onCountDownFinished();
6554d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    }
6654d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu
6754d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    private void remainingSecondsChanged(int newVal) {
6854d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        mRemainingSecs = newVal;
6954d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        if (newVal == 0) {
7054d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            // Countdown has finished
7154d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            setVisibility(View.INVISIBLE);
7254d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            mListener.onCountDownFinished();
7354d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        } else {
7454d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            Locale locale = getResources().getConfiguration().locale;
7554d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            String localizedValue = String.format(locale, "%d", newVal);
7654d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            mRemainingSecondsView.setText(localizedValue);
7754d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            // Fade-out animation
7854d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            mCountDownAnim.reset();
7954d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            mRemainingSecondsView.clearAnimation();
8054d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            mRemainingSecondsView.startAnimation(mCountDownAnim);
8154d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu
8254d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            // Play sound effect for the last 3 seconds of the countdown
838e3b1df4fcc770965d0796ac2046ef9e265d4bdbDoris Liu            if (mPlaySound) {
848e3b1df4fcc770965d0796ac2046ef9e265d4bdbDoris Liu                if (newVal == 1) {
858e3b1df4fcc770965d0796ac2046ef9e265d4bdbDoris Liu                    mSoundPool.play(mBeepTwice, 1.0f, 1.0f, 0, 0, 1.0f);
868e3b1df4fcc770965d0796ac2046ef9e265d4bdbDoris Liu                } else if (newVal <= 3) {
878e3b1df4fcc770965d0796ac2046ef9e265d4bdbDoris Liu                    mSoundPool.play(mBeepOnce, 1.0f, 1.0f, 0, 0, 1.0f);
888e3b1df4fcc770965d0796ac2046ef9e265d4bdbDoris Liu                }
8954d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            }
9054d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            // Schedule the next remainingSecondsChanged() call in 1 second
9154d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            mHandler.sendEmptyMessageDelayed(SET_TIMER_TEXT, 1000);
9254d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        }
9354d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    }
9454d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu
9554d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    @Override
9654d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    protected void onFinishInflate() {
9754d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        super.onFinishInflate();
9854d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        mRemainingSecondsView = (TextView) findViewById(R.id.remaining_seconds);
9954d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    }
10054d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu
10154d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    public void setCountDownFinishedListener(OnCountDownFinishedListener listener) {
10254d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        mListener = listener;
10354d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    }
10454d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu
1058e3b1df4fcc770965d0796ac2046ef9e265d4bdbDoris Liu    public void startCountDown(int sec, boolean playSound) {
10654d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        if (sec <= 0) {
10754d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            Log.w(TAG, "Invalid input for countdown timer: " + sec + " seconds");
10854d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            return;
10954d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        }
11054d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        setVisibility(View.VISIBLE);
1118e3b1df4fcc770965d0796ac2046ef9e265d4bdbDoris Liu        mPlaySound = playSound;
11254d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        remainingSecondsChanged(sec);
11354d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    }
11454d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu
11554d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    public void cancelCountDown() {
11654d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        if (mRemainingSecs > 0) {
11754d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            mRemainingSecs = 0;
11854d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            mHandler.removeMessages(SET_TIMER_TEXT);
11954d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            setVisibility(View.INVISIBLE);
12054d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        }
12154d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    }
12254d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu
12354d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    private class MainHandler extends Handler {
12454d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        @Override
12554d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        public void handleMessage(Message message) {
12654d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            if (message.what == SET_TIMER_TEXT) {
12754d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu                remainingSecondsChanged(mRemainingSecs -1);
12854d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu            }
12954d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu        }
13054d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu    }
13154d2fafcbb85025ea737c56af6df2afbf4bfda96Doris Liu}