1ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen/*
2ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen * Copyright (C) 2009 The Android Open Source Project
3ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen *
4ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen * Licensed under the Apache License, Version 2.0 (the "License");
5ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen * you may not use this file except in compliance with the License.
6ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen * You may obtain a copy of the License at
7ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen *
8ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen *      http://www.apache.org/licenses/LICENSE-2.0
9ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen *
10ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen * Unless required by applicable law or agreed to in writing, software
11ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen * distributed under the License is distributed on an "AS IS" BASIS,
12ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen * See the License for the specific language governing permissions and
14ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen * limitations under the License.
15ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen */
16ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
17ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenpackage com.android.scoaudiotest;
18ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
19ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.app.Activity;
20ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.bluetooth.BluetoothAdapter;
21ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.bluetooth.BluetoothDevice;
22ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.bluetooth.BluetoothHeadset;
23ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.bluetooth.BluetoothProfile;
24ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.content.BroadcastReceiver;
25ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.content.Context;
26ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.content.Intent;
27ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.content.IntentFilter;
28ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.content.res.AssetFileDescriptor;
29ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.media.AudioManager;
30ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.media.MediaPlayer;
31ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.media.MediaRecorder;
32ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.os.Bundle;
33ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.os.Environment;
34ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.os.Handler;
35ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.speech.tts.TextToSpeech;
36ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
37ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.util.Log;
38ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.view.KeyEvent;
39ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.view.View;
40ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.view.View.OnClickListener;
41ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.ArrayAdapter;
42ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.CheckBox;
43ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.CompoundButton;
44ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.CompoundButton.OnCheckedChangeListener;
45ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.EditText;
46ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.ImageButton;
47ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.ImageView;
48ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.Spinner;
49ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.TextView;
50ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport android.widget.ToggleButton;
51ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
52ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport java.io.File;
53ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport java.util.HashMap;
54ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport java.util.List;
55ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenimport java.util.Locale;
56ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
57ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissenpublic class ScoAudioTest extends Activity {
58ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
59ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    final static String TAG = "ScoAudioTest";
60ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
61ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    AudioManager mAudioManager;
62ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    AudioManager mAudioManager2;
63ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    boolean mForceScoOn;
64ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    ToggleButton mScoButton;
65ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    ToggleButton mVoiceDialerButton;
66ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    boolean mVoiceDialerOn;
67ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    String mLastRecordedFile;
68ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    SimpleMediaController mMediaControllers[] = new SimpleMediaController[2];
69ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private TextToSpeech mTts;
70ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private HashMap<String, String> mTtsParams;
71ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private int mOriginalVoiceVolume;
72ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    EditText mSpeakText;
73ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    boolean mTtsInited;
74ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private Handler mHandler;
75ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private static final String UTTERANCE = "utterance";
76ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private static Intent sVoiceCommandIntent;
77ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private File mSampleFile;
78ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    ToggleButton mTtsToFileButton;
79ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private boolean mTtsToFile;
80ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private int mCurrentMode;
81ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    Spinner mModeSpinner;
82ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private BluetoothHeadset mBluetoothHeadset;
83ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private BluetoothDevice mBluetoothHeadsetDevice;
84ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    TextView mScoStateTxt;
85ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    TextView mVdStateTxt;
86ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
87ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private final BroadcastReceiver mReceiver = new ScoBroadcastReceiver();
88ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
89ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    public ScoAudioTest() {
90ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        Log.e(TAG, "contructor");
91ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
92ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
93ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    /** Called when the activity is first created. */
94ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    @Override
95ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    public void onCreate(Bundle icicle) {
96ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        super.onCreate(icicle);
97ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
98ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        setContentView(R.layout.scoaudiotest);
99ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
10051efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette        mScoStateTxt = findViewById(R.id.scoStateTxt);
10151efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette        mVdStateTxt = findViewById(R.id.vdStateTxt);
102ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
103ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        IntentFilter intentFilter =
104ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            new IntentFilter(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED);
105ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        intentFilter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED);
106ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        intentFilter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
107ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        registerReceiver(mReceiver, intentFilter);
108ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
109ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
110ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mAudioManager2 = (AudioManager) getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
111ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mHandler = new Handler();
112ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
113ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mMediaControllers[0] = new SimplePlayerController(this, R.id.playPause1, R.id.stop1,
114ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                R.raw.sine440_mo_16b_16k, AudioManager.STREAM_BLUETOOTH_SCO);
11551efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette        TextView name = findViewById(R.id.playPause1Text);
116ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        name.setText("VOICE_CALL stream");
117ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
118ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mScoButton = (ToggleButton)findViewById(R.id.ForceScoButton);
119ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mScoButton.setOnCheckedChangeListener(mForceScoChanged);
120ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mForceScoOn = false;
121ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mScoButton.setChecked(mForceScoOn);
122ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
123ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mVoiceDialerButton = (ToggleButton)findViewById(R.id.VoiceDialerButton);
124ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mVoiceDialerButton.setOnCheckedChangeListener(mVoiceDialerChanged);
125ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mVoiceDialerOn = false;
126ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mVoiceDialerButton.setChecked(mVoiceDialerOn);
127ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
128ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
129ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mMediaControllers[1] = new SimpleRecordController(this, R.id.recStop1, 0, "Sco_record_");
130ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTtsInited = false;
131ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTts = new TextToSpeech(this, new TtsInitListener());
132ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTtsParams = new HashMap<String, String>();
133ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTtsParams.put(TextToSpeech.Engine.KEY_PARAM_STREAM,
134ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                String.valueOf(AudioManager.STREAM_BLUETOOTH_SCO));
135ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTtsParams.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID,
136ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                UTTERANCE);
137ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
13851efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette        mSpeakText = findViewById(R.id.speakTextEdit);
139ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mSpeakText.setOnKeyListener(mSpeakKeyListener);
140ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mSpeakText.setText("sco audio test sentence");
141ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTtsToFileButton = (ToggleButton)findViewById(R.id.TtsToFileButton);
142ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTtsToFileButton.setOnCheckedChangeListener(mTtsToFileChanged);
143ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTtsToFile = true;
144ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTtsToFileButton.setChecked(mTtsToFile);
145ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
14651efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette        mModeSpinner = findViewById(R.id.modeSpinner);
147ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
148ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                android.R.layout.simple_spinner_item, mModeStrings);
149ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
150ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mModeSpinner.setAdapter(adapter);
151ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mModeSpinner.setOnItemSelectedListener(mModeChanged);
152ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mCurrentMode = mAudioManager.getMode();
153ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mModeSpinner.setSelection(mCurrentMode);
154ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
155ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mBluetoothHeadsetDevice = null;
156ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
157ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        if (btAdapter != null) {
158ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            btAdapter.getProfileProxy(this, mBluetoothProfileServiceListener,
159ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                    BluetoothProfile.HEADSET);
160ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
161ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
162ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        sVoiceCommandIntent = new Intent(Intent.ACTION_VOICE_COMMAND);
163ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        sVoiceCommandIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
164ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
165ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
166ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    @Override
167ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    public void onDestroy() {
168ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        super.onDestroy();
169ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mTts.shutdown();
170ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        unregisterReceiver(mReceiver);
171ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        if (mBluetoothHeadset != null) {
172ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
173ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (btAdapter != null) {
174ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                btAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
175ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
176ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
177ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
178ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
179ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    @Override
180ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    protected void onPause() {
181ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        super.onPause();
182ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen//        mForceScoOn = false;
183ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen//        mScoButton.setChecked(mForceScoOn);
184ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mMediaControllers[0].stop();
185ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mMediaControllers[1].stop();
186ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO,
187ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mOriginalVoiceVolume, 0);
188ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
189ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
190ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    @Override
191ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    protected void onResume() {
192ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        super.onResume();
193ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mLastRecordedFile = "";
194ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mMediaControllers[0].mFileName = "";
195ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mOriginalVoiceVolume = mAudioManager.getStreamVolume(
196ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                AudioManager.STREAM_BLUETOOTH_SCO);
197ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        setVolumeControlStream(AudioManager.STREAM_BLUETOOTH_SCO);
198ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mCurrentMode = mAudioManager.getMode();
199ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        mModeSpinner.setSelection(mCurrentMode);
200ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
201ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
202ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private OnCheckedChangeListener mForceScoChanged
203ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    = new OnCheckedChangeListener(){
204ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
205ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onCheckedChanged(CompoundButton buttonView,
206ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                boolean isChecked) {
207ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mForceScoOn != isChecked) {
208ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mForceScoOn = isChecked;
209ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                AudioManager mngr = mAudioManager;
2101cff3844da64c3fc751ca0e047a6369d96c2c12eEric Laurent                boolean useVirtualCall = false;
21151efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette                CheckBox box = findViewById(R.id.useSecondAudioManager);
212ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                if (box.isChecked()) {
213ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    Log.i(TAG, "Using 2nd audio manager");
214ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mngr = mAudioManager2;
215ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
21651efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette                box = findViewById(R.id.useVirtualCallCheckBox);
2171cff3844da64c3fc751ca0e047a6369d96c2c12eEric Laurent                useVirtualCall = box.isChecked();
218ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
219ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                if (mForceScoOn) {
2201cff3844da64c3fc751ca0e047a6369d96c2c12eEric Laurent                    if (useVirtualCall) {
2211cff3844da64c3fc751ca0e047a6369d96c2c12eEric Laurent                        Log.e(TAG, "startBluetoothScoVirtualCall() IN");
2221cff3844da64c3fc751ca0e047a6369d96c2c12eEric Laurent                        mngr.startBluetoothScoVirtualCall();
2231cff3844da64c3fc751ca0e047a6369d96c2c12eEric Laurent                        Log.e(TAG, "startBluetoothScoVirtualCall() OUT");
2241cff3844da64c3fc751ca0e047a6369d96c2c12eEric Laurent                    } else {
2251cff3844da64c3fc751ca0e047a6369d96c2c12eEric Laurent                        Log.e(TAG, "startBluetoothSco() IN");
2261cff3844da64c3fc751ca0e047a6369d96c2c12eEric Laurent                        mngr.startBluetoothSco();
2271cff3844da64c3fc751ca0e047a6369d96c2c12eEric Laurent                        Log.e(TAG, "startBluetoothSco() OUT");
2281cff3844da64c3fc751ca0e047a6369d96c2c12eEric Laurent                    }
229ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                } else {
230ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    Log.e(TAG, "stopBluetoothSco() IN");
231ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mngr.stopBluetoothSco();
232ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    Log.e(TAG, "stopBluetoothSco() OUT");
233ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
234ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
235ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
236ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    };
237ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
238ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private OnCheckedChangeListener mVoiceDialerChanged
239ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    = new OnCheckedChangeListener(){
240ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
241ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onCheckedChanged(CompoundButton buttonView,
242ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                boolean isChecked) {
243ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mVoiceDialerOn != isChecked) {
244ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mVoiceDialerOn = isChecked;
245ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                if (mBluetoothHeadset != null && mBluetoothHeadsetDevice != null) {
246ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    if (mVoiceDialerOn) {
247ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mBluetoothHeadset.startVoiceRecognition(mBluetoothHeadsetDevice);
248ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    } else {
249ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mBluetoothHeadset.stopVoiceRecognition(mBluetoothHeadsetDevice);
250ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    }
251ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
252ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
253ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
254ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    };
255ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
256ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private OnCheckedChangeListener mTtsToFileChanged
257ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    = new OnCheckedChangeListener(){
258ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
259ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onCheckedChanged(CompoundButton buttonView,
260ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                boolean isChecked) {
261ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mTtsToFile = isChecked;
262ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
263ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    };
264ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
265ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private class SimpleMediaController implements OnClickListener {
266ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        int mPlayPauseButtonId;
267ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        int mStopButtonId;
268ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        Context mContext;
269ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        ImageView mPlayPauseButton;
270ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        int mPlayImageResource;
271ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        int mPauseImageResource;
272ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        String mFileNameBase;
273ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        String mFileName;
274ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        int mFileResId;
275ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
276ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        SimpleMediaController(Context context, int playPausebuttonId, int stopButtonId, String fileName) {
277ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mContext = context;
278ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayPauseButtonId = playPausebuttonId;
279ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mStopButtonId = stopButtonId;
280ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mFileNameBase = fileName;
28151efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette            mPlayPauseButton = findViewById(playPausebuttonId);
28251efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette            ImageButton stop = findViewById(stopButtonId);
283ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
284ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayPauseButton.setOnClickListener(this);
285ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayPauseButton.requestFocus();
286ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (stop != null) {
287ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                stop.setOnClickListener(this);
288ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
289ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
290ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
291ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        SimpleMediaController(Context context, int playPausebuttonId, int stopButtonId, int fileResId) {
292ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mContext = context;
293ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayPauseButtonId = playPausebuttonId;
294ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mStopButtonId = stopButtonId;
295ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mFileNameBase = "";
296ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mFileResId = fileResId;
29751efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette            mPlayPauseButton = findViewById(playPausebuttonId);
29851efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette            ImageButton stop = findViewById(stopButtonId);
299ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
300ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayPauseButton.setOnClickListener(this);
301ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayPauseButton.requestFocus();
302ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (stop != null) {
303ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                stop.setOnClickListener(this);
304ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
305ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
306ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
307ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
308ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onClick(View v) {
309ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (v.getId() == mPlayPauseButtonId) {
310ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                playOrPause();
311ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            } else if (v.getId() == mStopButtonId) {
312ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                stop();
313ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
314ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
315ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
316ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void playOrPause() {
317ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
318ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
319ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void stop() {
320ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
321ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
322ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public boolean isPlaying() {
323ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            return false;
324ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
325ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
326ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void updatePlayPauseButton() {
327ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayPauseButton.setImageResource(isPlaying() ? mPauseImageResource : mPlayImageResource);
328ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
329ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
330ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
331ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private class SimplePlayerController extends SimpleMediaController {
332ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        private MediaPlayer mMediaPlayer;
333ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        private int mStreamType;
334ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        SimplePlayerController(Context context, int playPausebuttonId, int stopButtonId, String fileName, int stream) {
335ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            super(context, playPausebuttonId, stopButtonId, fileName);
336ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
337ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayImageResource = android.R.drawable.ic_media_play;
338ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPauseImageResource = android.R.drawable.ic_media_pause;
339ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mStreamType = stream;
340ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mFileName = Environment.getExternalStorageDirectory().toString() + "/music/" +
341ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mFileNameBase + "_" + ".wav";
342ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
343ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
344ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        SimplePlayerController(Context context, int playPausebuttonId, int stopButtonId, int fileResId, int stream) {
345ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            super(context, playPausebuttonId, stopButtonId, fileResId);
346ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
347ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayImageResource = android.R.drawable.ic_media_play;
348ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPauseImageResource = android.R.drawable.ic_media_pause;
349ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mStreamType = stream;
350ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mFileName = "";
351ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
352ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
353ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
354ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void playOrPause() {
355ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            Log.e(TAG, "playOrPause playing: "+((mMediaPlayer == null)?false:!mMediaPlayer.isPlaying())+
356ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    " mMediaPlayer: "+mMediaPlayer+
357ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    " mFileName: "+mFileName+
358ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    " mLastRecordedFile: "+mLastRecordedFile);
359ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mMediaPlayer == null || !mMediaPlayer.isPlaying()){
360ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                if (mMediaPlayer == null) {
361ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    if (mFileName != mLastRecordedFile) {
362ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mFileName = mLastRecordedFile;
363ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        Log.e(TAG, "new recorded file: "+mFileName);
364ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    }
365ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    try {
366ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mMediaPlayer = new MediaPlayer();
367ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        if (mFileName.equals("")) {
368ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            Log.e(TAG, "Playing from resource");
369ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(mFileResId);
370ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
371ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            afd.close();
372ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        } else {
373ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            Log.e(TAG, "Playing file: "+mFileName);
374ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            mMediaPlayer.setDataSource(mFileName);
375ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        }
376ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mMediaPlayer.setAudioStreamType(mStreamType);
377ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mMediaPlayer.prepare();
378ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mMediaPlayer.setLooping(true);
379ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    } catch (Exception ex) {
380ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        Log.e(TAG, "mMediaPlayercreate failed:", ex);
381ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mMediaPlayer.release();
382ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mMediaPlayer = null;
383ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    }
384ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
385ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    if (mMediaPlayer != null) {
386ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
387ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            @Override
388ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            public void onCompletion(MediaPlayer mp) {
389ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                updatePlayPauseButton();
390ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            }
391ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        });
392ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    }
393ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
394ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                if (mMediaPlayer != null) {
395ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mMediaPlayer.start();
396ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
397ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            } else {
398ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mMediaPlayer.pause();
399ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
400ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            updatePlayPauseButton();
401ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
402ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
403ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void stop() {
404ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mMediaPlayer != null) {
405ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mMediaPlayer.stop();
406ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mMediaPlayer.release();
407ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mMediaPlayer = null;
408ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
409ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            updatePlayPauseButton();
410ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
411ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
412ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
413ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public boolean isPlaying() {
414ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mMediaPlayer != null) {
415ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                return mMediaPlayer.isPlaying();
416ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            } else {
417ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                return false;
418ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
419ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
420ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
421ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
422ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private class SimpleRecordController extends SimpleMediaController {
423ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        private MediaRecorder mMediaRecorder;
424ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        private int mFileCount = 0;
425ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        private int mState = 0;
426ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        SimpleRecordController(Context context, int playPausebuttonId, int stopButtonId, String fileName) {
427ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            super(context, playPausebuttonId, stopButtonId, fileName);
428ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            Log.e(TAG, "SimpleRecordController cstor");
429ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPlayImageResource = R.drawable.record;
430ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mPauseImageResource = R.drawable.stop;
431ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
432ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
433ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
434ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void playOrPause() {
435ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mState == 0) {
436ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                setup();
437ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                try {
438ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mMediaRecorder.start();
439ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mState = 1;
440ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                } catch (Exception e) {
4411b7dba8d50030568a67f5f9f99b1b2f8c367e6a4Eric Laurent                    Log.e(TAG, "Could start MediaRecorder: ", e);
442ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mMediaRecorder.release();
443ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mMediaRecorder = null;
444ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mState = 0;
445ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
446ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            } else {
447ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                try {
448ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mMediaRecorder.stop();
449ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mMediaRecorder.reset();
450ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                } catch (Exception e) {
4511b7dba8d50030568a67f5f9f99b1b2f8c367e6a4Eric Laurent                    Log.e(TAG, "Could not stop MediaRecorder: ", e);
452ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mMediaRecorder.release();
453ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mMediaRecorder = null;
454ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                } finally {
455ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mState = 0;
456ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
457ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
458ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            updatePlayPauseButton();
459ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
460ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
461ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void setup() {
462ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            Log.e(TAG, "SimpleRecordController setup()");
463ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mMediaRecorder == null) {
464ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mMediaRecorder = new MediaRecorder();
465ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
466ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
467ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
468ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
469ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mFileName = Environment.getExternalStorageDirectory().toString() + "/music/" +
470ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mFileNameBase + "_" + ++mFileCount + ".amr";
471ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mLastRecordedFile = mFileName;
472ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            Log.e(TAG, "recording to file: "+mLastRecordedFile);
473ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mMediaRecorder.setOutputFile(mFileName);
474ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            try {
475ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mMediaRecorder.prepare();
476ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
477ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            catch (Exception e) {
4781b7dba8d50030568a67f5f9f99b1b2f8c367e6a4Eric Laurent                Log.e(TAG, "Could not prepare MediaRecorder: ", e);
479ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mMediaRecorder.release();
480ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mMediaRecorder = null;
481ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
482ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
483ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
484ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
485ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void stop() {
486ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mMediaRecorder != null) {
4871b7dba8d50030568a67f5f9f99b1b2f8c367e6a4Eric Laurent                try {
4881b7dba8d50030568a67f5f9f99b1b2f8c367e6a4Eric Laurent                    mMediaRecorder.stop();
4891b7dba8d50030568a67f5f9f99b1b2f8c367e6a4Eric Laurent                } catch (Exception e) {
4901b7dba8d50030568a67f5f9f99b1b2f8c367e6a4Eric Laurent                    Log.e(TAG, "Could not stop MediaRecorder: ", e);
4911b7dba8d50030568a67f5f9f99b1b2f8c367e6a4Eric Laurent                } finally {
4921b7dba8d50030568a67f5f9f99b1b2f8c367e6a4Eric Laurent                    mMediaRecorder.release();
4931b7dba8d50030568a67f5f9f99b1b2f8c367e6a4Eric Laurent                    mMediaRecorder = null;
4941b7dba8d50030568a67f5f9f99b1b2f8c367e6a4Eric Laurent                }
495ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
496ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            updatePlayPauseButton();
497ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
498ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
499ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
500ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public boolean isPlaying() {
501ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mState == 1) {
502ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                return true;
503ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            } else {
504ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                return false;
505ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
506ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
507ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
508ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
509ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    class TtsInitListener implements TextToSpeech.OnInitListener {
510ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
511ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onInit(int status) {
512ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            // status can be either TextToSpeech.SUCCESS or TextToSpeech.ERROR.
513ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            Log.e(TAG, "onInit for tts");
514ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (status != TextToSpeech.SUCCESS) {
515ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                // Initialization failed.
516ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                Log.e(TAG, "Could not initialize TextToSpeech.");
517ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                return;
518ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
519ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
520ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mTts == null) {
521ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                Log.e(TAG, "null tts");
522ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                return;
523ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
524ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
525ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            int result = mTts.setLanguage(Locale.US);
526ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (result == TextToSpeech.LANG_MISSING_DATA ||
527ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                result == TextToSpeech.LANG_NOT_SUPPORTED) {
528ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen               // Lanuage data is missing or the language is not supported.
529ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                Log.e(TAG, "Language is not available.");
530ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                return;
531ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
532ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mTts.setOnUtteranceCompletedListener(new MyUtteranceCompletedListener(UTTERANCE));
533ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mTtsInited = true;
534ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen         }
535ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
536ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
537ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    class MyUtteranceCompletedListener implements OnUtteranceCompletedListener {
538ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        private final String mExpectedUtterance;
539ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
540ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public MyUtteranceCompletedListener(String expectedUtteranceId) {
541ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mExpectedUtterance = expectedUtteranceId;
542ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
543ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
544ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
545ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onUtteranceCompleted(String utteranceId) {
546ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            Log.e(TAG, "onUtteranceCompleted " + utteranceId);
547ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mTtsToFile) {
548ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                if (mSampleFile != null && mSampleFile.exists()) {
549ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    MediaPlayer mediaPlayer = new MediaPlayer();
550ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    try {
551ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mediaPlayer.setDataSource(mSampleFile.getPath());
552ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mediaPlayer.setAudioStreamType(AudioManager.STREAM_BLUETOOTH_SCO);
553ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mediaPlayer.prepare();
554ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    } catch (Exception ex) {
555ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        Log.e(TAG, "mMediaPlayercreate failed:", ex);
556ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mediaPlayer.release();
557ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mediaPlayer = null;
558ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    }
559ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
560ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    if (mediaPlayer != null) {
561ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
562ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            @Override
563ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            public void onCompletion(MediaPlayer mp) {
564ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                mp.release();
565ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                if (mSampleFile != null && mSampleFile.exists()) {
566ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                    mSampleFile.delete();
567ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                    mSampleFile = null;
568ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                }
569ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                              mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO,
570ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                              mOriginalVoiceVolume, 0);
571ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen//                              Debug.stopMethodTracing();
572ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            }
573ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        });
574ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mediaPlayer.start();
575ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    }
576ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                } else {
577ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    Log.e(TAG, "synthesizeToFile did not create file");
578ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
579ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            } else {
580ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO,
581ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mOriginalVoiceVolume, 0);
582ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen//                Debug.stopMethodTracing();
583ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
584ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
585ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            Log.e(TAG, "end speak, volume: "+mOriginalVoiceVolume);
586ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
587ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
588ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
589ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
590ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private View.OnKeyListener mSpeakKeyListener
591ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    = new View.OnKeyListener() {
592ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
593ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public boolean onKey(View v, int keyCode, KeyEvent event) {
594ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (event.getAction() == KeyEvent.ACTION_DOWN) {
595ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                switch (keyCode) {
596ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    case KeyEvent.KEYCODE_DPAD_CENTER:
597ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    case KeyEvent.KEYCODE_ENTER:
598ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        if (!mTtsInited) {
599ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            Log.e(TAG, "Tts not inited ");
600ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            return false;
601ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        }
602ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mOriginalVoiceVolume = mAudioManager.getStreamVolume(
603ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                AudioManager.STREAM_BLUETOOTH_SCO);
604ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        Log.e(TAG, "start speak, volume: "+mOriginalVoiceVolume);
605ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mAudioManager.setStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO,
606ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                mOriginalVoiceVolume/2, 0);
607ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
608ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        // we now have SCO connection and TTS, so we can start.
609ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        mHandler.post(new Runnable() {
610ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            @Override
611ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            public void run() {
612ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen//                                Debug.startMethodTracing("tts");
613ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
614ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                if (mTtsToFile) {
615ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                    if (mSampleFile != null && mSampleFile.exists()) {
616ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                        mSampleFile.delete();
617ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                        mSampleFile = null;
618ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                    }
619ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                    mSampleFile = new File(Environment.getExternalStorageDirectory(), "mytts.wav");
620ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                    mTts.synthesizeToFile(mSpeakText.getText().toString(), mTtsParams, mSampleFile.getPath());
621ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                } else {
622ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                    mTts.speak(mSpeakText.getText().toString(),
623ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                        TextToSpeech.QUEUE_FLUSH,
624ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                        mTtsParams);
625ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                                }
626ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                            }
627ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        });
628ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        return true;
629ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
630ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
631ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            return false;
632ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
633ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    };
634ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
635ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private static final String[] mModeStrings = {
636ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        "NORMAL", "RINGTONE", "IN_CALL", "IN_COMMUNICATION"
637ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    };
638ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
639ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private Spinner.OnItemSelectedListener mModeChanged
640ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        = new Spinner.OnItemSelectedListener() {
641ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
642ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onItemSelected(android.widget.AdapterView av, View v,
643ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    int position, long id) {
644ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mCurrentMode != position) {
645ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mCurrentMode = position;
646ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mAudioManager.setMode(mCurrentMode);
647ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
648ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
649ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
650ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
651ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onNothingSelected(android.widget.AdapterView av) {
652ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
653ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    };
654ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
655ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
656ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        new BluetoothProfile.ServiceListener() {
657ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
658ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onServiceConnected(int profile, BluetoothProfile proxy) {
659ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            mBluetoothHeadset = (BluetoothHeadset) proxy;
660ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
661ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (deviceList.size() > 0) {
662ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mBluetoothHeadsetDevice = deviceList.get(0);
663ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            } else {
664ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mBluetoothHeadsetDevice = null;
665ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
666ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
667ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
668ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onServiceDisconnected(int profile) {
669ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (mBluetoothHeadset != null) {
670ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                List<BluetoothDevice> devices = mBluetoothHeadset.getConnectedDevices();
671ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                if (devices.size() == 0) {
672ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mBluetoothHeadsetDevice = null;
673ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
674ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mBluetoothHeadset = null;
675ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
676ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
677ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    };
678ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
679ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private int mChangedState = -1;
680ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private int mUpdatedState = -1;
681ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private int mUpdatedPrevState = -1;
682ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
683ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    private class ScoBroadcastReceiver extends BroadcastReceiver {
684ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        @Override
685ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        public void onReceive(Context context, Intent intent) {
686ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            String action = intent.getAction();
687ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
688ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            if (action.equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
689ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, -1);
690ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mVdStateTxt.setText(Integer.toString(state));
691ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                Log.e(TAG, "BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED: "+state);
692ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            } else if (action.equals(AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED)) {
693ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mChangedState = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
694ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                Log.e(TAG, "ACTION_SCO_AUDIO_STATE_CHANGED: "+mChangedState);
695ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mScoStateTxt.setText("changed: "+Integer.toString(mChangedState)+
696ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        " updated: "+Integer.toString(mUpdatedState)+
697ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        " prev updated: "+Integer.toString(mUpdatedPrevState));
698ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            } else if (action.equals(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)) {
699ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mUpdatedState = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, -1);
700ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mUpdatedPrevState = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_PREVIOUS_STATE, -1);
701ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                Log.e(TAG, "ACTION_SCO_AUDIO_STATE_UPDATED, state: "+mUpdatedState+" prev state: "+mUpdatedPrevState);
702ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                mScoStateTxt.setText("changed: "+Integer.toString(mChangedState)+
703ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        " updated: "+Integer.toString(mUpdatedState)+
704ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                        " prev updated: "+Integer.toString(mUpdatedPrevState));
705ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                if (mForceScoOn && mUpdatedState == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) {
706ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mForceScoOn = false;
707ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mScoButton.setChecked(mForceScoOn);
708ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                    mAudioManager.stopBluetoothSco();
709ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen                }
710ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen            }
711ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen        }
712ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen    }
713ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen
714ef02abd50531952b263061eeff6003f2605e91d5Marco Nelissen}
715