/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.scoaudiotest;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.ToggleButton;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

public class ScoAudioTest extends Activity {

    final static String TAG = "ScoAudioTest";
    
    AudioManager mAudioManager;
    AudioManager mAudioManager2;
    boolean mForceScoOn;
    ToggleButton mScoButton;
    ToggleButton mVoiceDialerButton;
    boolean mVoiceDialerOn;
    String mLastRecordedFile;
    SimpleMediaController mMediaControllers[] = new SimpleMediaController[2];
    private TextToSpeech mTts;
    private HashMap<String, String> mTtsParams;
    private int mOriginalVoiceVolume;
    EditText mSpeakText;
    boolean mTtsInited;
    private Handler mHandler;
    private static final String UTTERANCE = "utterance";
    private static Intent sVoiceCommandIntent;
    private File mSampleFile;
    ToggleButton mTtsToFileButton;
    private boolean mTtsToFile;
    private int mCurrentMode;
    Spinner mModeSpinner;
    private BluetoothHeadset mBluetoothHeadset;
    private BluetoothDevice mBluetoothHeadsetDevice;
    TextView mScoStateTxt;
    TextView mVdStateTxt;
    
    private final BroadcastReceiver mReceiver = new ScoBroadcastReceiver();

    public ScoAudioTest() {
        Log.e(TAG, "contructor");
    }
        
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        
        setContentView(R.layout.scoaudiotest);

        mScoStateTxt = (TextView) findViewById(R.id.scoStateTxt);
        mVdStateTxt = (TextView) findViewById(R.id.vdStateTxt);

        IntentFilter intentFilter =
            new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
        intentFilter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED);
        intentFilter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
        registerReceiver(mReceiver, intentFilter);

        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        mAudioManager2 = (AudioManager) getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
        mHandler = new Handler();
        
        mMediaControllers[0] = new SimplePlayerController(this, R.id.playPause1, R.id.stop1,
                R.raw.sine440_mo_16b_16k, AudioManager.STREAM_BLUETOOTH_SCO);
        TextView name = (TextView) findViewById(R.id.playPause1Text);
        name.setText("VOICE_CALL stream");
        
        mScoButton = (ToggleButton)findViewById(R.id.ForceScoButton);
        mScoButton.setOnCheckedChangeListener(mForceScoChanged);
        mForceScoOn = false;
        mScoButton.setChecked(mForceScoOn);

        mVoiceDialerButton = (ToggleButton)findViewById(R.id.VoiceDialerButton);
        mVoiceDialerButton.setOnCheckedChangeListener(mVoiceDialerChanged);
        mVoiceDialerOn = false;
        mVoiceDialerButton.setChecked(mVoiceDialerOn);

        
        mMediaControllers[1] = new SimpleRecordController(this, R.id.recStop1, 0, "Sco_record_");
        mTtsInited = false;
        mTts = new TextToSpeech(this, new TtsInitListener());
        mTtsParams = new HashMap<String, String>();
        mTtsParams.put(TextToSpeech.Engine.KEY_PARAM_STREAM,
                String.valueOf(AudioManager.STREAM_BLUETOOTH_SCO));
        mTtsParams.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,
                UTTERANCE);

        mSpeakText = (EditText) findViewById(R.id.speakTextEdit);        
        mSpeakText.setOnKeyListener(mSpeakKeyListener);
        mSpeakText.setText("sco audio test sentence");
        mTtsToFileButton = (ToggleButton)findViewById(R.id.TtsToFileButton);
        mTtsToFileButton.setOnCheckedChangeListener(mTtsToFileChanged);
        mTtsToFile = true;
        mTtsToFileButton.setChecked(mTtsToFile);

        mModeSpinner = (Spinner) findViewById(R.id.modeSpinner);
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_item, mModeStrings);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mModeSpinner.setAdapter(adapter);
        mModeSpinner.setOnItemSelectedListener(mModeChanged);
        mCurrentMode = mAudioManager.getMode();
        mModeSpinner.setSelection(mCurrentMode);

        mBluetoothHeadsetDevice = null;
        BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
        if (btAdapter != null) {
            btAdapter.getProfileProxy(this, mBluetoothProfileServiceListener,
                                    BluetoothProfile.HEADSET);
        }

        sVoiceCommandIntent = new Intent(Intent.ACTION_VOICE_COMMAND);
        sVoiceCommandIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mTts.shutdown();
        unregisterReceiver(mReceiver);
        if (mBluetoothHeadset != null) {
            BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
            if (btAdapter != null) {
                btAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
            }
        }
    }
    
    @Override
    protected void onPause() {
        super.onPause();
//        mForceScoOn = false;
//        mScoButton.setChecked(mForceScoOn);
        mMediaControllers[0].stop();        
        mMediaControllers[1].stop();
        mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO,
                mOriginalVoiceVolume, 0);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mLastRecordedFile = "";
        mMediaControllers[0].mFileName = "";
        mOriginalVoiceVolume = mAudioManager.getStreamVolume(
                AudioManager.STREAM_BLUETOOTH_SCO);
        setVolumeControlStream(AudioManager.STREAM_BLUETOOTH_SCO);
        mCurrentMode = mAudioManager.getMode();
        mModeSpinner.setSelection(mCurrentMode);
    }

    private OnCheckedChangeListener mForceScoChanged
    = new OnCheckedChangeListener(){
        @Override
        public void onCheckedChanged(CompoundButton buttonView,
                boolean isChecked) {
            if (mForceScoOn != isChecked) {
                mForceScoOn = isChecked;
                AudioManager mngr = mAudioManager;
                boolean useVirtualCall = false;
                CheckBox box = (CheckBox) findViewById(R.id.useSecondAudioManager);
                if (box.isChecked()) {
                    Log.i(TAG, "Using 2nd audio manager");
                    mngr = mAudioManager2;
                }
                box = (CheckBox) findViewById(R.id.useVirtualCallCheckBox);
                useVirtualCall = box.isChecked();

                if (mForceScoOn) {
                    if (useVirtualCall) {
                        Log.e(TAG, "startBluetoothScoVirtualCall() IN");
                        mngr.startBluetoothScoVirtualCall();
                        Log.e(TAG, "startBluetoothScoVirtualCall() OUT");
                    } else {
                        Log.e(TAG, "startBluetoothSco() IN");
                        mngr.startBluetoothSco();
                        Log.e(TAG, "startBluetoothSco() OUT");
                    }
                } else {
                    Log.e(TAG, "stopBluetoothSco() IN");
                    mngr.stopBluetoothSco();
                    Log.e(TAG, "stopBluetoothSco() OUT");
                }
            }
        }
    };

    private OnCheckedChangeListener mVoiceDialerChanged
    = new OnCheckedChangeListener(){
        @Override
        public void onCheckedChanged(CompoundButton buttonView,
                boolean isChecked) {
            if (mVoiceDialerOn != isChecked) {
                mVoiceDialerOn = isChecked;
                if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) {
                    if (mVoiceDialerOn) {
                        mBluetoothHeadset.startVoiceRecognition(mBluetoothHeadsetDevice);
                    } else {
                        mBluetoothHeadset.stopVoiceRecognition(mBluetoothHeadsetDevice);                        
                    }
                }
            }
        }
    };

    private OnCheckedChangeListener mTtsToFileChanged
    = new OnCheckedChangeListener(){
        @Override
        public void onCheckedChanged(CompoundButton buttonView,
                boolean isChecked) {
            mTtsToFile = isChecked;
        }
    };

    private class SimpleMediaController implements OnClickListener {
        int mPlayPauseButtonId;
        int mStopButtonId;
        Context mContext;
        ImageView mPlayPauseButton;
        int mPlayImageResource;
        int mPauseImageResource;
        String mFileNameBase;
        String mFileName;
        int mFileResId;
        
        SimpleMediaController(Context context, int playPausebuttonId, int stopButtonId, String fileName) {
            mContext = context;
            mPlayPauseButtonId = playPausebuttonId;
            mStopButtonId = stopButtonId;
            mFileNameBase = fileName;
            mPlayPauseButton = (ImageButton) findViewById(playPausebuttonId);
            ImageButton stop = (ImageButton) findViewById(stopButtonId);

            mPlayPauseButton.setOnClickListener(this);
            mPlayPauseButton.requestFocus();
            if (stop != null) {
                stop.setOnClickListener(this);
            }
        }

        SimpleMediaController(Context context, int playPausebuttonId, int stopButtonId, int fileResId) {
            mContext = context;
            mPlayPauseButtonId = playPausebuttonId;
            mStopButtonId = stopButtonId;
            mFileNameBase = "";
            mFileResId = fileResId;
            mPlayPauseButton = (ImageButton) findViewById(playPausebuttonId);
            ImageButton stop = (ImageButton) findViewById(stopButtonId);

            mPlayPauseButton.setOnClickListener(this);
            mPlayPauseButton.requestFocus();
            if (stop != null) {
                stop.setOnClickListener(this);
            }
        }

        @Override
        public void onClick(View v) {
            if (v.getId() == mPlayPauseButtonId) {
                playOrPause();
            } else if (v.getId() == mStopButtonId) {
                stop();
            }
        }
        
        public void playOrPause() {
        }
        
        public void stop() {
        }

        public boolean isPlaying() {
            return false;
        }

        public void updatePlayPauseButton() {
            mPlayPauseButton.setImageResource(isPlaying() ? mPauseImageResource : mPlayImageResource);
        }
    }
    
    private class SimplePlayerController extends SimpleMediaController {
        private MediaPlayer mMediaPlayer;
        private int mStreamType;
        SimplePlayerController(Context context, int playPausebuttonId, int stopButtonId, String fileName, int stream) {
            super(context, playPausebuttonId, stopButtonId, fileName);
            
            mPlayImageResource = android.R.drawable.ic_media_play;
            mPauseImageResource = android.R.drawable.ic_media_pause;
            mStreamType = stream;
            mFileName = Environment.getExternalStorageDirectory().toString() + "/music/" +
                        mFileNameBase + "_" + ".wav";
        }

        SimplePlayerController(Context context, int playPausebuttonId, int stopButtonId, int fileResId, int stream) {
            super(context, playPausebuttonId, stopButtonId, fileResId);
            
            mPlayImageResource = android.R.drawable.ic_media_play;
            mPauseImageResource = android.R.drawable.ic_media_pause;
            mStreamType = stream;
            mFileName = "";
        }

        @Override
        public void playOrPause() {
            Log.e(TAG, "playOrPause playing: "+((mMediaPlayer == null)?false:!mMediaPlayer.isPlaying())+
                    " mMediaPlayer: "+mMediaPlayer+
                    " mFileName: "+mFileName+
                    " mLastRecordedFile: "+mLastRecordedFile);
            if (mMediaPlayer == null || !mMediaPlayer.isPlaying()){
                if (mMediaPlayer == null) {
                    if (mFileName != mLastRecordedFile) {
                        mFileName = mLastRecordedFile;
                        Log.e(TAG, "new recorded file: "+mFileName);
                    }
                    try {
                        mMediaPlayer = new MediaPlayer();
                        if (mFileName.equals("")) {
                            Log.e(TAG, "Playing from resource");
                            AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(mFileResId);
                            mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                            afd.close();
                        } else {
                            Log.e(TAG, "Playing file: "+mFileName);
                            mMediaPlayer.setDataSource(mFileName);
                        }
                        mMediaPlayer.setAudioStreamType(mStreamType);
                        mMediaPlayer.prepare();
                        mMediaPlayer.setLooping(true);
                    } catch (Exception ex) {
                        Log.e(TAG, "mMediaPlayercreate failed:", ex);
                        mMediaPlayer.release();
                        mMediaPlayer = null;
                    }

                    if (mMediaPlayer != null) {
                        mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                            @Override
                            public void onCompletion(MediaPlayer mp) {
                                updatePlayPauseButton();
                            }
                        });
                    }
                }
                if (mMediaPlayer != null) {
                    mMediaPlayer.start();
                }
            } else {
                mMediaPlayer.pause();
            }
            updatePlayPauseButton();
        }
        @Override
        public void stop() {
            if (mMediaPlayer != null) {
                mMediaPlayer.stop();
                mMediaPlayer.release();
                mMediaPlayer = null;
            }
            updatePlayPauseButton();
        }
        
        @Override
        public boolean isPlaying() {
            if (mMediaPlayer != null) {
                return mMediaPlayer.isPlaying();
            } else {
                return false;                
            }
        }
    }
    
    private class SimpleRecordController extends SimpleMediaController {
        private MediaRecorder mMediaRecorder;
        private int mFileCount = 0;
        private int mState = 0;
        SimpleRecordController(Context context, int playPausebuttonId, int stopButtonId, String fileName) {
            super(context, playPausebuttonId, stopButtonId, fileName);
            Log.e(TAG, "SimpleRecordController cstor");
            mPlayImageResource = R.drawable.record;
            mPauseImageResource = R.drawable.stop;
        }
       
        @Override
        public void playOrPause() {
            if (mState == 0) {
                setup();
                try {
                    mMediaRecorder.start();
                    mState = 1;
                } catch (Exception e) {
                    Log.e(TAG, "Could start MediaRecorder: ", e);
                    mMediaRecorder.release();
                    mMediaRecorder = null;
                    mState = 0;
                }
            } else {
                try {
                    mMediaRecorder.stop();
                    mMediaRecorder.reset();
                } catch (Exception e) {
                    Log.e(TAG, "Could not stop MediaRecorder: ", e);
                    mMediaRecorder.release();
                    mMediaRecorder = null;
                } finally {
                    mState = 0;
                }
            }
            updatePlayPauseButton();
        }

        public void setup() {
            Log.e(TAG, "SimpleRecordController setup()");
            if (mMediaRecorder == null) {
                mMediaRecorder = new MediaRecorder();
            }
            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            mFileName = Environment.getExternalStorageDirectory().toString() + "/music/" +
                        mFileNameBase + "_" + ++mFileCount + ".amr";
            mLastRecordedFile = mFileName;
            Log.e(TAG, "recording to file: "+mLastRecordedFile);
            mMediaRecorder.setOutputFile(mFileName);
            try {
                mMediaRecorder.prepare();
            }
            catch (Exception e) {
                Log.e(TAG, "Could not prepare MediaRecorder: ", e);
                mMediaRecorder.release();
                mMediaRecorder = null;
            }
        }
        
        @Override
        public void stop() {
            if (mMediaRecorder != null) {
                try {
                    mMediaRecorder.stop();
                } catch (Exception e) {
                    Log.e(TAG, "Could not stop MediaRecorder: ", e);
                } finally {
                    mMediaRecorder.release();
                    mMediaRecorder = null;
                }
            }
            updatePlayPauseButton();
        }

        @Override
        public boolean isPlaying() {
            if (mState == 1) {
                return true;
            } else {
                return false;                
            }
        }
    }
    
    class TtsInitListener implements TextToSpeech.OnInitListener {
        @Override
        public void onInit(int status) {
            // status can be either TextToSpeech.SUCCESS or TextToSpeech.ERROR.
            Log.e(TAG, "onInit for tts");
            if (status != TextToSpeech.SUCCESS) {
                // Initialization failed.
                Log.e(TAG, "Could not initialize TextToSpeech.");
                return;
            }

            if (mTts == null) {
                Log.e(TAG, "null tts");
                return;
            }

            int result = mTts.setLanguage(Locale.US);
            if (result == TextToSpeech.LANG_MISSING_DATA ||
                result == TextToSpeech.LANG_NOT_SUPPORTED) {
               // Lanuage data is missing or the language is not supported.
                Log.e(TAG, "Language is not available.");
                return;
            }
            mTts.setOnUtteranceCompletedListener(new MyUtteranceCompletedListener(UTTERANCE));
            mTtsInited = true;
         }
    }

    class MyUtteranceCompletedListener implements OnUtteranceCompletedListener {
        private final String mExpectedUtterance;
        
        public MyUtteranceCompletedListener(String expectedUtteranceId) {
            mExpectedUtterance = expectedUtteranceId;
        }
        
        @Override
        public void onUtteranceCompleted(String utteranceId) {
            Log.e(TAG, "onUtteranceCompleted " + utteranceId);
            if (mTtsToFile) {
                if (mSampleFile != null && mSampleFile.exists()) {
                    MediaPlayer mediaPlayer = new MediaPlayer();
                    try {
                        mediaPlayer.setDataSource(mSampleFile.getPath());
                        mediaPlayer.setAudioStreamType(AudioManager.STREAM_BLUETOOTH_SCO);
                        mediaPlayer.prepare();
                    } catch (Exception ex) {
                        Log.e(TAG, "mMediaPlayercreate failed:", ex);
                        mediaPlayer.release();
                        mediaPlayer = null;
                    }
    
                    if (mediaPlayer != null) {
                        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                            @Override
                            public void onCompletion(MediaPlayer mp) {
                                mp.release();
                                if (mSampleFile != null && mSampleFile.exists()) {
                                    mSampleFile.delete();
                                    mSampleFile = null;
                                }
                              mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO,
                              mOriginalVoiceVolume, 0);
//                              Debug.stopMethodTracing();
                            }
                        });
                        mediaPlayer.start();
                    }
                } else {
                    Log.e(TAG, "synthesizeToFile did not create file");
                }
            } else {
                mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO,
                        mOriginalVoiceVolume, 0);
//                Debug.stopMethodTracing();
            }
            
            Log.e(TAG, "end speak, volume: "+mOriginalVoiceVolume);
        }
    }

    
    private View.OnKeyListener mSpeakKeyListener
    = new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_DOWN) {
                switch (keyCode) {
                    case KeyEvent.KEYCODE_DPAD_CENTER:
                    case KeyEvent.KEYCODE_ENTER:
                        if (!mTtsInited) {
                            Log.e(TAG, "Tts not inited ");
                            return false;
                        }
                        mOriginalVoiceVolume = mAudioManager.getStreamVolume(
                                AudioManager.STREAM_BLUETOOTH_SCO);
                        Log.e(TAG, "start speak, volume: "+mOriginalVoiceVolume);
                        mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO,
                                mOriginalVoiceVolume/2, 0);

                        // we now have SCO connection and TTS, so we can start.
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
//                                Debug.startMethodTracing("tts");

                                if (mTtsToFile) {
                                    if (mSampleFile != null && mSampleFile.exists()) {
                                        mSampleFile.delete();
                                        mSampleFile = null;
                                    }
                                    mSampleFile = new File(Environment.getExternalStorageDirectory(), "mytts.wav");
                                    mTts.synthesizeToFile(mSpeakText.getText().toString(), mTtsParams, mSampleFile.getPath());
                                } else {
                                    mTts.speak(mSpeakText.getText().toString(),
                                        TextToSpeech.QUEUE_FLUSH,
                                        mTtsParams);
                                }
                            }
                        });
                        return true;
                }
            }
            return false;
        }
    };
    
    private static final String[] mModeStrings = {
        "NORMAL", "RINGTONE", "IN_CALL", "IN_COMMUNICATION"
    };
    
    private Spinner.OnItemSelectedListener mModeChanged
        = new Spinner.OnItemSelectedListener() {
        @Override
        public void onItemSelected(android.widget.AdapterView av, View v,
                    int position, long id) {
            if (mCurrentMode != position) {
                mCurrentMode = position;
                mAudioManager.setMode(mCurrentMode);
            }
        }
        
        @Override
        public void onNothingSelected(android.widget.AdapterView av) {
        }
    };

    private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
        new BluetoothProfile.ServiceListener() {
        @Override
        public void onServiceConnected(int profile, BluetoothProfile proxy) {
            mBluetoothHeadset = (BluetoothHeadset) proxy;
            List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
            if (deviceList.size() > 0) {
                mBluetoothHeadsetDevice = deviceList.get(0);
            } else {
                mBluetoothHeadsetDevice = null;
            }
        }
        @Override
        public void onServiceDisconnected(int profile) {
            if (mBluetoothHeadset != null) {
                List<BluetoothDevice> devices = mBluetoothHeadset.getConnectedDevices();
                if (devices.size() == 0) {
                    mBluetoothHeadsetDevice = null;
                }
                mBluetoothHeadset = null;
            }
        }
    };

    private int mChangedState = -1;
    private int mUpdatedState = -1;
    private int mUpdatedPrevState = -1;
    
    private class ScoBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

            if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
                int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
                mVdStateTxt.setText(Integer.toString(state));
                Log.e(TAG, "BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED: "+state);
            } else if (action.equals(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED)) {
                mChangedState = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
                Log.e(TAG, "ACTION_SCO_AUDIO_STATE_CHANGED: "+mChangedState);
                mScoStateTxt.setText("changed: "+Integer.toString(mChangedState)+ 
                        " updated: "+Integer.toString(mUpdatedState)+
                        " prev updated: "+Integer.toString(mUpdatedPrevState));
            } else if (action.equals(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)) {
                mUpdatedState = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
                mUpdatedPrevState = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_PREVIOUS_STATE, -1);
                Log.e(TAG, "ACTION_SCO_AUDIO_STATE_UPDATED, state: "+mUpdatedState+" prev state: "+mUpdatedPrevState);
                mScoStateTxt.setText("changed: "+Integer.toString(mChangedState)+ 
                        " updated: "+Integer.toString(mUpdatedState)+
                        " prev updated: "+Integer.toString(mUpdatedPrevState));
                if (mForceScoOn && mUpdatedState == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) {
                    mForceScoOn = false;
                    mScoButton.setChecked(mForceScoOn);
                    mAudioManager.stopBluetoothSco();
                }
            }
        }
    }

}
