Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(641)

Side by Side Diff: webrtc/examples/androidapp/src/org/appspot/apprtc/AppRTCAudioManager.java

Issue 2408063008: Extends how AppRTCMobile handles audio focus on Android (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698