OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2014 The WebRTC Project Authors. All rights reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 // Contains the currently selected audio device. | 68 // Contains the currently selected audio device. |
69 private AudioDevice selectedAudioDevice; | 69 private AudioDevice selectedAudioDevice; |
70 | 70 |
71 // Contains a list of available audio devices. A Set collection is used to | 71 // Contains a list of available audio devices. A Set collection is used to |
72 // avoid duplicate elements. | 72 // avoid duplicate elements. |
73 private final Set<AudioDevice> audioDevices = new HashSet<AudioDevice>(); | 73 private final Set<AudioDevice> audioDevices = new HashSet<AudioDevice>(); |
74 | 74 |
75 // Broadcast receiver for wired headset intent broadcasts. | 75 // Broadcast receiver for wired headset intent broadcasts. |
76 private BroadcastReceiver wiredHeadsetReceiver; | 76 private BroadcastReceiver wiredHeadsetReceiver; |
77 | 77 |
| 78 // Callback method for changes in audio focus. |
| 79 private AudioManager.OnAudioFocusChangeListener audioFocusChangeListener; |
| 80 |
78 // This method is called when the proximity sensor reports a state change, | 81 // This method is called when the proximity sensor reports a state change, |
79 // e.g. from "NEAR to FAR" or from "FAR to NEAR". | 82 // e.g. from "NEAR to FAR" or from "FAR to NEAR". |
80 private void onProximitySensorChangedState() { | 83 private void onProximitySensorChangedState() { |
81 if (!useSpeakerphone.equals(SPEAKERPHONE_AUTO)) { | 84 if (!useSpeakerphone.equals(SPEAKERPHONE_AUTO)) { |
82 return; | 85 return; |
83 } | 86 } |
84 | 87 |
85 // The proximity sensor should only be activated when there are exactly two | 88 // The proximity sensor should only be activated when there are exactly two |
86 // available audio devices. | 89 // available audio devices. |
87 if (audioDevices.size() == 2 && audioDevices.contains(AppRTCAudioManager.Aud
ioDevice.EARPIECE) | 90 if (audioDevices.size() == 2 && audioDevices.contains(AppRTCAudioManager.Aud
ioDevice.EARPIECE) |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 Log.d(TAG, "init"); | 139 Log.d(TAG, "init"); |
137 if (initialized) { | 140 if (initialized) { |
138 return; | 141 return; |
139 } | 142 } |
140 | 143 |
141 // Store current audio state so we can restore it when close() is called. | 144 // Store current audio state so we can restore it when close() is called. |
142 savedAudioMode = audioManager.getMode(); | 145 savedAudioMode = audioManager.getMode(); |
143 savedIsSpeakerPhoneOn = audioManager.isSpeakerphoneOn(); | 146 savedIsSpeakerPhoneOn = audioManager.isSpeakerphoneOn(); |
144 savedIsMicrophoneMute = audioManager.isMicrophoneMute(); | 147 savedIsMicrophoneMute = audioManager.isMicrophoneMute(); |
145 | 148 |
146 // Request audio focus before making any device switch. | 149 // Create an AudioManager.OnAudioFocusChangeListener instance. |
147 audioManager.requestAudioFocus( | 150 audioFocusChangeListener = new AudioManager.OnAudioFocusChangeListener() { |
148 null, AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN_TRANS
IENT); | 151 // Called on the listener to notify if the audio focus for this listener h
as been changed. |
| 152 // The |focusChange| value indicates whether the focus was gained, whether
the focus was lost, |
| 153 // and whether that loss is transient, or whether the new focus holder wil
l hold it for an |
| 154 // unknown amount of time. |
| 155 // TODO(henrika): possibly extend support of handling audio-focus changes.
Only contains |
| 156 // logging for now. |
| 157 @Override |
| 158 public void onAudioFocusChange(int focusChange) { |
| 159 String typeOfChange = "AUDIOFOCUS_NOT_DEFINED"; |
| 160 switch (focusChange) { |
| 161 case AudioManager.AUDIOFOCUS_GAIN: |
| 162 typeOfChange = "AUDIOFOCUS_GAIN"; |
| 163 break; |
| 164 case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT: |
| 165 typeOfChange = "AUDIOFOCUS_GAIN_TRANSIENT"; |
| 166 break; |
| 167 case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE: |
| 168 typeOfChange = "AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE"; |
| 169 break; |
| 170 case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK: |
| 171 typeOfChange = "AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK"; |
| 172 break; |
| 173 case AudioManager.AUDIOFOCUS_LOSS: |
| 174 typeOfChange = "AUDIOFOCUS_LOSS"; |
| 175 break; |
| 176 case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: |
| 177 typeOfChange = "AUDIOFOCUS_LOSS_TRANSIENT"; |
| 178 break; |
| 179 case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: |
| 180 typeOfChange = "AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK"; |
| 181 break; |
| 182 default: |
| 183 typeOfChange = "AUDIOFOCUS_INVALID"; |
| 184 break; |
| 185 } |
| 186 Log.d(TAG, "onAudioFocusChange: " + typeOfChange); |
| 187 } |
| 188 }; |
| 189 |
| 190 // Request audio playout focus (without ducking) and install listener for ch
anges in focus. |
| 191 int result = audioManager.requestAudioFocus(audioFocusChangeListener, |
| 192 AudioManager.STREAM_VOICE_CALL, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT); |
| 193 if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { |
| 194 Log.d(TAG, "Audio focus request granted for VOICE_CALL streams"); |
| 195 } else { |
| 196 Log.e(TAG, "Audio focus request failed"); |
| 197 } |
149 | 198 |
150 // Start by setting MODE_IN_COMMUNICATION as default audio mode. It is | 199 // Start by setting MODE_IN_COMMUNICATION as default audio mode. It is |
151 // required to be in this mode when playout and/or recording starts for | 200 // required to be in this mode when playout and/or recording starts for |
152 // best possible VoIP performance. | 201 // best possible VoIP performance. |
153 // TODO(henrika): we migh want to start with RINGTONE mode here instead. | 202 // TODO(henrika): we migh want to start with RINGTONE mode here instead. |
154 audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); | 203 audioManager.setMode(AudioManager.MODE_IN_COMMUNICATION); |
155 | 204 |
156 // Always disable microphone mute during a WebRTC call. | 205 // Always disable microphone mute during a WebRTC call. |
157 setMicrophoneMute(false); | 206 setMicrophoneMute(false); |
158 | 207 |
(...skipping 14 matching lines...) Expand all Loading... |
173 if (!initialized) { | 222 if (!initialized) { |
174 return; | 223 return; |
175 } | 224 } |
176 | 225 |
177 unregisterForWiredHeadsetIntentBroadcast(); | 226 unregisterForWiredHeadsetIntentBroadcast(); |
178 | 227 |
179 // Restore previously stored audio states. | 228 // Restore previously stored audio states. |
180 setSpeakerphoneOn(savedIsSpeakerPhoneOn); | 229 setSpeakerphoneOn(savedIsSpeakerPhoneOn); |
181 setMicrophoneMute(savedIsMicrophoneMute); | 230 setMicrophoneMute(savedIsMicrophoneMute); |
182 audioManager.setMode(savedAudioMode); | 231 audioManager.setMode(savedAudioMode); |
183 audioManager.abandonAudioFocus(null); | 232 |
| 233 // Abandon audio focus. Gives the previous focus owner, if any, focus. |
| 234 audioManager.abandonAudioFocus(audioFocusChangeListener); |
| 235 audioFocusChangeListener = null; |
| 236 Log.d(TAG, "Abandoned audio focus for VOICE_CALL streams"); |
184 | 237 |
185 if (proximitySensor != null) { | 238 if (proximitySensor != null) { |
186 proximitySensor.stop(); | 239 proximitySensor.stop(); |
187 proximitySensor = null; | 240 proximitySensor = null; |
188 } | 241 } |
189 | 242 |
190 initialized = false; | 243 initialized = false; |
191 } | 244 } |
192 | 245 |
193 /** Changes selection of the currently active audio device. */ | 246 /** Changes selection of the currently active audio device. */ |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 Log.e(TAG, "Invalid device list"); | 410 Log.e(TAG, "Invalid device list"); |
358 } | 411 } |
359 | 412 |
360 if (onStateChangeListener != null) { | 413 if (onStateChangeListener != null) { |
361 // Run callback to notify a listening client. The client can then | 414 // Run callback to notify a listening client. The client can then |
362 // use public getters to query the new state. | 415 // use public getters to query the new state. |
363 onStateChangeListener.run(); | 416 onStateChangeListener.run(); |
364 } | 417 } |
365 } | 418 } |
366 } | 419 } |
OLD | NEW |