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}