AudioTestFragment.java revision 46371473c416415fb6bcb8db85686669c3d65af6
1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.google.android.car.kitchensink.audio;
18
19import android.car.Car;
20import android.car.CarAppFocusManager;
21import android.car.CarAppFocusManager.AppFocusChangeListener;
22import android.car.CarAppFocusManager.AppFocusOwnershipChangeListener;
23import android.car.CarNotConnectedException;
24import android.car.media.CarAudioManager;
25import android.content.ComponentName;
26import android.content.Context;
27import android.content.ServiceConnection;
28import android.media.AudioAttributes;
29import android.media.AudioManager;
30import android.os.Bundle;
31import android.os.Handler;
32import android.os.IBinder;
33import android.os.Looper;
34import android.support.v4.app.Fragment;
35import android.util.Log;
36import android.view.LayoutInflater;
37import android.view.View;
38import android.view.View.OnClickListener;
39import android.view.ViewGroup;
40import android.widget.Button;
41import android.widget.CompoundButton;
42import android.widget.CompoundButton.OnCheckedChangeListener;
43import android.widget.RadioGroup;
44import android.widget.TextView;
45import android.widget.ToggleButton;
46
47import com.google.android.car.kitchensink.CarEmulator;
48import com.google.android.car.kitchensink.R;
49import com.google.android.car.kitchensink.audio.AudioPlayer.PlayStateListener;
50
51public class AudioTestFragment extends Fragment {
52    private static final String TAG = "CAR.AUDIO.KS";
53    private static final boolean DBG = true;
54
55    private AudioManager mAudioManager;
56    private FocusHandler mAudioFocusHandler;
57    private Button mNavPlayOnce;
58    private Button mVrPlayOnce;
59    private Button mSystemPlayOnce;
60    private Button mMediaPlay;
61    private Button mMediaPlayOnce;
62    private Button mMediaStop;
63    private Button mWavPlay;
64    private Button mWavStop;
65    private Button mNavStart;
66    private Button mNavEnd;
67    private Button mVrStart;
68    private Button mVrEnd;
69    private Button mRadioStart;
70    private Button mRadioEnd;
71    private Button mSpeakerPhoneOn;
72    private Button mSpeakerPhoneOff;
73    private Button mMicrophoneOn;
74    private Button mMicrophoneOff;
75    private ToggleButton mEnableMocking;
76    private ToggleButton mRejectFocus;
77    private ToggleButton mMuteMedia;
78
79    private AudioPlayer mMusicPlayer;
80    private AudioPlayer mMusicPlayerShort;
81    private AudioPlayer mNavGuidancePlayer;
82    private AudioPlayer mVrPlayer;
83    private AudioPlayer mSystemPlayer;
84    private AudioPlayer mWavPlayer;
85    private AudioPlayer[] mAllPlayers;
86
87    private Handler mHandler;
88    private Context mContext;
89
90    private Car mCar;
91    private CarAppFocusManager mAppFocusManager;
92    private CarAudioManager mCarAudioManager;
93    private AudioAttributes mMusicAudioAttrib;
94    private AudioAttributes mNavAudioAttrib;
95    private AudioAttributes mVrAudioAttrib;
96    private AudioAttributes mRadioAudioAttrib;
97    private AudioAttributes mSystemSoundAudioAttrib;
98    private CarEmulator mCarEmulator;
99
100    private final AudioManager.OnAudioFocusChangeListener mNavFocusListener =
101            new AudioManager.OnAudioFocusChangeListener() {
102                @Override
103                public void onAudioFocusChange(int focusChange) {
104                    Log.i(TAG, "Nav focus change:" + focusChange);
105                }
106    };
107    private final AudioManager.OnAudioFocusChangeListener mVrFocusListener =
108            new AudioManager.OnAudioFocusChangeListener() {
109                @Override
110                public void onAudioFocusChange(int focusChange) {
111                    Log.i(TAG, "VR focus change:" + focusChange);
112                }
113    };
114    private final AudioManager.OnAudioFocusChangeListener mRadioFocusListener =
115            new AudioManager.OnAudioFocusChangeListener() {
116                @Override
117                public void onAudioFocusChange(int focusChange) {
118                    Log.i(TAG, "Radio focus change:" + focusChange);
119                }
120    };
121
122    private final AppFocusOwnershipChangeListener mOwnershipListener =
123            new AppFocusOwnershipChangeListener() {
124                @Override
125                public void onAppFocusOwnershipLoss(int focus) {
126                }
127    };
128
129    private void init() {
130        mContext = getContext();
131        mHandler = new Handler(Looper.getMainLooper());
132        mCar = Car.createCar(mContext, new ServiceConnection() {
133            @Override
134            public void onServiceConnected(ComponentName name, IBinder service) {
135                try {
136                    mAppFocusManager =
137                            (CarAppFocusManager) mCar.getCarManager(Car.APP_FOCUS_SERVICE);
138                } catch (CarNotConnectedException e) {
139                    throw new RuntimeException("Failed to create app focus manager", e);
140                }
141                try {
142                    AppFocusChangeListener listener = new AppFocusChangeListener() {
143                        @Override
144                        public void onAppFocusChange(int appType, boolean active) {
145                        }
146                    };
147                    mAppFocusManager.registerFocusListener(listener,
148                            CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION);
149                    mAppFocusManager.registerFocusListener(listener,
150                            CarAppFocusManager.APP_FOCUS_TYPE_VOICE_COMMAND);
151                } catch (CarNotConnectedException e) {
152                    Log.e(TAG, "Failed to register focus listener", e);
153                }
154                try {
155                    mCarAudioManager = (CarAudioManager) mCar.getCarManager(Car.AUDIO_SERVICE);
156                } catch (CarNotConnectedException e) {
157                    throw new RuntimeException("Failed to create audio manager", e);
158                }
159                mMusicAudioAttrib = mCarAudioManager.getAudioAttributesForCarUsage(
160                        CarAudioManager.CAR_AUDIO_USAGE_MUSIC);
161                mNavAudioAttrib = mCarAudioManager.getAudioAttributesForCarUsage(
162                        CarAudioManager.CAR_AUDIO_USAGE_NAVIGATION_GUIDANCE);
163                mVrAudioAttrib = mCarAudioManager.getAudioAttributesForCarUsage(
164                        CarAudioManager.CAR_AUDIO_USAGE_VOICE_COMMAND);
165                mRadioAudioAttrib = mCarAudioManager.getAudioAttributesForCarUsage(
166                        CarAudioManager.CAR_AUDIO_USAGE_RADIO);
167                mSystemSoundAudioAttrib = mCarAudioManager.getAudioAttributesForCarUsage(
168                        CarAudioManager.CAR_AUDIO_USAGE_SYSTEM_SOUND);
169
170                mMusicPlayer = new AudioPlayer(mContext, R.raw.john_harrison_with_the_wichita_state_university_chamber_players_05_summer_mvt_2_adagio,
171                        mMusicAudioAttrib);
172                mMusicPlayerShort = new AudioPlayer(mContext, R.raw.ring_classic_01,
173                        mMusicAudioAttrib);
174                mNavGuidancePlayer = new AudioPlayer(mContext, R.raw.turnright,
175                        mNavAudioAttrib);
176                // no Usage for voice command yet.
177                mVrPlayer = new AudioPlayer(mContext, R.raw.one2six,
178                        mVrAudioAttrib);
179                mSystemPlayer = new AudioPlayer(mContext, R.raw.ring_classic_01,
180                        mSystemSoundAudioAttrib);
181                mWavPlayer = new AudioPlayer(mContext, R.raw.free_flight,
182                        mMusicAudioAttrib);
183                mAllPlayers = new AudioPlayer[] {
184                        mMusicPlayer,
185                        mMusicPlayerShort,
186                        mNavGuidancePlayer,
187                        mVrPlayer,
188                        mSystemPlayer,
189                        mWavPlayer
190                };
191            }
192            @Override
193            public void onServiceDisconnected(ComponentName name) {
194            }
195            }, Looper.getMainLooper());
196        mCar.connect();
197    }
198
199    @Override
200    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
201        Log.i(TAG, "onCreateView");
202        init();
203        View view = inflater.inflate(R.layout.audio, container, false);
204        mAudioManager = (AudioManager) mContext.getSystemService(
205                Context.AUDIO_SERVICE);
206        mAudioFocusHandler = new FocusHandler(
207                (RadioGroup) view.findViewById(R.id.button_focus_request_selection),
208                (Button) view.findViewById(R.id.button_audio_focus_request),
209                (TextView) view.findViewById(R.id.text_audio_focus_state));
210        mMediaPlay = (Button) view.findViewById(R.id.button_media_play_start);
211        mMediaPlay.setOnClickListener(new OnClickListener() {
212            @Override
213            public void onClick(View v) {
214                mMusicPlayer.start(false, true, AudioManager.AUDIOFOCUS_GAIN);
215            }
216        });
217        mMediaPlayOnce = (Button) view.findViewById(R.id.button_media_play_once);
218        mMediaPlayOnce.setOnClickListener(new OnClickListener() {
219            @Override
220            public void onClick(View v) {
221                mMusicPlayerShort.start(true, false, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
222                // play only for 1 sec and stop
223                mHandler.postDelayed(new Runnable() {
224                    @Override
225                    public void run() {
226                        mMusicPlayerShort.stop();
227                    }
228                }, 1000);
229            }
230        });
231        mMediaStop = (Button) view.findViewById(R.id.button_media_play_stop);
232        mMediaStop.setOnClickListener(new OnClickListener() {
233            @Override
234            public void onClick(View v) {
235                mMusicPlayer.stop();
236            }
237        });
238        mWavPlay = (Button) view.findViewById(R.id.button_wav_play_start);
239        mWavPlay.setOnClickListener(new OnClickListener() {
240            @Override
241            public void onClick(View v) {
242                mWavPlayer.start(true, true, AudioManager.AUDIOFOCUS_GAIN);
243            }
244        });
245        mWavStop = (Button) view.findViewById(R.id.button_wav_play_stop);
246        mWavStop.setOnClickListener(new OnClickListener() {
247            @Override
248            public void onClick(View v) {
249                mWavPlayer.stop();
250            }
251        });
252        mNavPlayOnce = (Button) view.findViewById(R.id.button_nav_play_once);
253        mNavPlayOnce.setOnClickListener(new OnClickListener() {
254            @Override
255            public void onClick(View v) {
256                if (mAppFocusManager == null) {
257                    return;
258                }
259                if (DBG) {
260                    Log.i(TAG, "Nav start");
261                }
262                if (!mNavGuidancePlayer.isPlaying()) {
263                    try {
264                        mAppFocusManager.requestAppFocus(mOwnershipListener,
265                                CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION);
266                    } catch (CarNotConnectedException e) {
267                        Log.e(TAG, "Failed to set active focus", e);
268                    }
269                    mNavGuidancePlayer.start(true, false,
270                            AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK,
271                            new PlayStateListener() {
272                        @Override
273                        public void onCompletion() {
274                            try {
275                                mAppFocusManager.abandonAppFocus(mOwnershipListener,
276                                        CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION);
277                            } catch (CarNotConnectedException e) {
278                                Log.e(TAG, "Failed to reset active focus", e);
279                            }
280                        }
281                    });
282                }
283            }
284        });
285        mVrPlayOnce = (Button) view.findViewById(R.id.button_vr_play_once);
286        mVrPlayOnce.setOnClickListener(new OnClickListener() {
287            @Override
288            public void onClick(View v) {
289                if (mAppFocusManager == null) {
290                    return;
291                }
292                if (DBG) {
293                    Log.i(TAG, "VR start");
294                }
295                try {
296                    mAppFocusManager.requestAppFocus(mOwnershipListener,
297                            CarAppFocusManager.APP_FOCUS_TYPE_VOICE_COMMAND);
298                } catch (CarNotConnectedException e) {
299                    Log.e(TAG, "Failed to set active focus", e);
300                }
301                if (!mVrPlayer.isPlaying()) {
302                    mVrPlayer.start(true, false, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT,
303                            new PlayStateListener() {
304                        @Override
305                        public void onCompletion() {
306                            try {
307                                mAppFocusManager.abandonAppFocus(mOwnershipListener,
308                                        CarAppFocusManager.APP_FOCUS_TYPE_VOICE_COMMAND);
309                            } catch (CarNotConnectedException e) {
310                                Log.e(TAG, "Failed to reset active focus", e);
311                            }
312                        }
313                    });
314                }
315            }
316        });
317        mSystemPlayOnce = (Button) view.findViewById(R.id.button_system_play_once);
318        mSystemPlayOnce.setOnClickListener(new OnClickListener() {
319            @Override
320            public void onClick(View v) {
321                if (DBG) {
322                    Log.i(TAG, "System start");
323                }
324                if (!mSystemPlayer.isPlaying()) {
325                    // system sound played without focus
326                    mSystemPlayer.start(false, false, 0);
327                }
328            }
329        });
330        mNavStart = (Button) view.findViewById(R.id.button_nav_start);
331        mNavStart.setOnClickListener(new OnClickListener() {
332            @Override
333            public void onClick(View v) {
334                handleNavStart();
335            }
336        });
337        mNavEnd = (Button) view.findViewById(R.id.button_nav_end);
338        mNavEnd.setOnClickListener(new OnClickListener() {
339            @Override
340            public void onClick(View v) {
341                handleNavEnd();
342            }
343        });
344        mVrStart = (Button) view.findViewById(R.id.button_vr_start);
345        mVrStart.setOnClickListener(new OnClickListener() {
346            @Override
347            public void onClick(View v) {
348                handleVrStart();
349            }
350        });
351        mVrEnd = (Button) view.findViewById(R.id.button_vr_end);
352        mVrEnd.setOnClickListener(new OnClickListener() {
353            @Override
354            public void onClick(View v) {
355                handleVrEnd();
356            }
357        });
358        mRadioStart = (Button) view.findViewById(R.id.button_radio_start);
359        mRadioStart.setOnClickListener(new OnClickListener() {
360            @Override
361            public void onClick(View v) {
362                handleRadioStart();
363            }
364        });
365        mRadioEnd = (Button) view.findViewById(R.id.button_radio_end);
366        mRadioEnd.setOnClickListener(new OnClickListener() {
367            @Override
368            public void onClick(View v) {
369                handleRadioEnd();
370            }
371        });
372        mSpeakerPhoneOn = (Button) view.findViewById(R.id.button_speaker_phone_on);
373        mSpeakerPhoneOn.setOnClickListener(new OnClickListener() {
374            @Override
375            public void onClick(View v) {
376                mAudioManager.setSpeakerphoneOn(true);
377            }
378        });
379        mSpeakerPhoneOff = (Button) view.findViewById(R.id.button_speaker_phone_off);
380        mSpeakerPhoneOff.setOnClickListener(new OnClickListener() {
381            @Override
382            public void onClick(View v) {
383                mAudioManager.setSpeakerphoneOn(false);
384            }
385        });
386        mMicrophoneOn = (Button) view.findViewById(R.id.button_microphone_on);
387        mMicrophoneOn.setOnClickListener(new OnClickListener() {
388            @Override
389            public void onClick(View v) {
390                mAudioManager.setMicrophoneMute(false); // Turn the microphone on.
391            }
392        });
393        mMicrophoneOff = (Button) view.findViewById(R.id.button_microphone_off);
394        mMicrophoneOff.setOnClickListener(new OnClickListener() {
395            @Override
396            public void onClick(View v) {
397                mAudioManager.setMicrophoneMute(true); // Mute the microphone.
398            }
399        });
400
401
402        mRejectFocus = (ToggleButton) view.findViewById(R.id.button_reject_audio_focus);
403        mRejectFocus.setOnCheckedChangeListener(new OnCheckedChangeListener() {
404            @Override
405            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
406                if (mCarEmulator == null) {
407                    return;
408                }
409                if (!mEnableMocking.isChecked()) {
410                    return;
411                }
412                if (isChecked) {
413                    mCarEmulator.setAudioFocusControl(true);
414                } else {
415                    mCarEmulator.setAudioFocusControl(false);
416                }
417            }
418        });
419        mRejectFocus.setActivated(false);
420        mEnableMocking = (ToggleButton) view.findViewById(R.id.button_mock_audio);
421        mEnableMocking.setOnCheckedChangeListener(new OnCheckedChangeListener() {
422            @Override
423            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
424                if (mCarEmulator == null) {
425                    mCarEmulator = new CarEmulator(mCar);
426                }
427                if (isChecked) {
428                    mRejectFocus.setActivated(true);
429                    mCarEmulator.start();
430                } else {
431                    mRejectFocus.setActivated(false);
432                    mCarEmulator.stop();
433                    mCarEmulator = null;
434                }
435            }
436        });
437        mMuteMedia = (ToggleButton) view.findViewById(R.id.button_mute_media);
438        mMuteMedia.setOnCheckedChangeListener(new OnCheckedChangeListener() {
439            @Override
440            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
441                try {
442                    if (isChecked) {
443                        mCarAudioManager.setMediaMute(true);
444                    } else {
445                        mCarAudioManager.setMediaMute(false);
446                    }
447                } catch (CarNotConnectedException e) {
448                    //ignore
449                }
450            }
451        });
452        return view;
453    }
454
455    @Override
456    public void onDestroyView() {
457        super.onDestroyView();
458        Log.i(TAG, "onDestroyView");
459        if (mCarEmulator != null) {
460            mCarEmulator.setAudioFocusControl(false);
461            mCarEmulator.stop();
462        }
463        for (AudioPlayer p : mAllPlayers) {
464            p.stop();
465        }
466        if (mAudioFocusHandler != null) {
467            mAudioFocusHandler.release();
468            mAudioFocusHandler = null;
469        }
470        if (mAppFocusManager != null) {
471            try {
472                mAppFocusManager.abandonAppFocus(mOwnershipListener);
473            } catch (CarNotConnectedException e) {
474                Log.e(TAG, "Failed to reset active focus", e);
475            }
476        }
477    }
478
479    private void handleNavStart() {
480        if (mAppFocusManager == null) {
481            return;
482        }
483        if (mCarAudioManager == null) {
484            return;
485        }
486        if (DBG) {
487            Log.i(TAG, "Nav start");
488        }
489        try {
490            mAppFocusManager.requestAppFocus(mOwnershipListener,
491                    CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION);
492        } catch (CarNotConnectedException e) {
493            Log.e(TAG, "Failed to set active focus", e);
494        }
495        mCarAudioManager.requestAudioFocus(mNavFocusListener, mNavAudioAttrib,
496                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK, 0);
497    }
498
499    private void handleNavEnd() {
500        if (mAppFocusManager == null) {
501            return;
502        }
503        if (mCarAudioManager == null) {
504            return;
505        }
506        if (DBG) {
507            Log.i(TAG, "Nav end");
508        }
509        try {
510            mAppFocusManager.abandonAppFocus(mOwnershipListener,
511                    CarAppFocusManager.APP_FOCUS_TYPE_NAVIGATION);
512        } catch (CarNotConnectedException e) {
513            Log.e(TAG, "Failed to reset active focus", e);
514        }
515        mCarAudioManager.abandonAudioFocus(mNavFocusListener, mNavAudioAttrib);
516    }
517
518    private void handleVrStart() {
519        if (mAppFocusManager == null) {
520            return;
521        }
522        if (mCarAudioManager == null) {
523            return;
524        }
525        if (DBG) {
526            Log.i(TAG, "VR start");
527        }
528        try {
529            mAppFocusManager.requestAppFocus(mOwnershipListener,
530                    CarAppFocusManager.APP_FOCUS_TYPE_VOICE_COMMAND);
531        } catch (CarNotConnectedException e) {
532            Log.e(TAG, "Failed to set active focus", e);
533        }
534        mCarAudioManager.requestAudioFocus(mVrFocusListener, mVrAudioAttrib,
535                AudioManager.AUDIOFOCUS_GAIN_TRANSIENT, 0);
536    }
537
538    private void handleVrEnd() {
539        if (mAppFocusManager == null) {
540            return;
541        }
542        if (mCarAudioManager == null) {
543            return;
544        }
545        if (DBG) {
546            Log.i(TAG, "VR end");
547        }
548        try {
549            mAppFocusManager.abandonAppFocus(mOwnershipListener,
550                    CarAppFocusManager.APP_FOCUS_TYPE_VOICE_COMMAND);
551        } catch (CarNotConnectedException e) {
552            Log.e(TAG, "Failed to reset active focus", e);
553        }
554        mCarAudioManager.abandonAudioFocus(mVrFocusListener, mVrAudioAttrib);
555    }
556
557    private void handleRadioStart() {
558        if (mCarAudioManager == null) {
559            return;
560        }
561        if (DBG) {
562            Log.i(TAG, "Radio start");
563        }
564        mCarAudioManager.requestAudioFocus(mRadioFocusListener, mRadioAudioAttrib,
565                AudioManager.AUDIOFOCUS_GAIN, 0);
566    }
567
568    private void handleRadioEnd() {
569        if (mCarAudioManager == null) {
570            return;
571        }
572        if (DBG) {
573            Log.i(TAG, "Radio end");
574        }
575        mCarAudioManager.abandonAudioFocus(mRadioFocusListener, mRadioAudioAttrib);
576    }
577
578    private class FocusHandler {
579        private static final String AUDIO_FOCUS_STATE_GAIN = "gain";
580        private static final String AUDIO_FOCUS_STATE_RELEASED_UNKNOWN = "released / unknown";
581
582        private final RadioGroup mRequestSelection;
583        private final TextView mText;
584        private final AudioFocusListener mFocusListener;
585
586        public FocusHandler(RadioGroup radioGroup, Button requestButton, TextView text) {
587            mText = text;
588            mRequestSelection = radioGroup;
589            mRequestSelection.check(R.id.focus_gain);
590            setFocusText(AUDIO_FOCUS_STATE_RELEASED_UNKNOWN);
591            mFocusListener = new AudioFocusListener();
592            requestButton.setOnClickListener(new OnClickListener() {
593                @Override
594                public void onClick(View v) {
595                    int selectedButtonId = mRequestSelection.getCheckedRadioButtonId();
596                    int focusRequest = AudioManager.AUDIOFOCUS_GAIN;
597                    if (selectedButtonId == R.id.focus_gain_transient_duck) {
598                        focusRequest = AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK;
599                    } else if (selectedButtonId == R.id.focus_release) {
600                        mAudioManager.abandonAudioFocus(mFocusListener);
601                        setFocusText(AUDIO_FOCUS_STATE_RELEASED_UNKNOWN);
602                        return;
603                    }
604                    int ret = mAudioManager.requestAudioFocus(mFocusListener,
605                            AudioManager.STREAM_MUSIC, focusRequest);
606                    Log.i(TAG, "requestAudioFocus returned " + ret);
607                    if (ret == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
608                        setFocusText(AUDIO_FOCUS_STATE_GAIN);
609                    }
610                }
611            });
612        }
613
614        public void release() {
615            abandonAudioFocus();
616        }
617
618        private void abandonAudioFocus() {
619            if (DBG) {
620                Log.i(TAG, "abandonAudioFocus");
621            }
622            mAudioManager.abandonAudioFocus(mFocusListener);
623            setFocusText(AUDIO_FOCUS_STATE_RELEASED_UNKNOWN);
624        }
625
626        private void setFocusText(String msg) {
627            mText.setText("focus state:" + msg);
628        }
629
630        private class AudioFocusListener implements AudioManager.OnAudioFocusChangeListener {
631            @Override
632            public void onAudioFocusChange(int focusChange) {
633                Log.i(TAG, "onAudioFocusChange " + focusChange);
634                if (focusChange == AudioManager.AUDIOFOCUS_GAIN) {
635                    setFocusText(AUDIO_FOCUS_STATE_GAIN);
636                } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS) {
637                    setFocusText("loss");
638                } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) {
639                    setFocusText("loss,transient");
640                } else if (focusChange == AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) {
641                    setFocusText("loss,transient,duck");
642                }
643            }
644        }
645    }
646}
647