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 |
11 package org.appspot.apprtc; | 11 package org.appspot.apprtc; |
12 | 12 |
13 import org.appspot.apprtc.util.AppRTCUtils; | 13 import org.appspot.apprtc.util.AppRTCUtils; |
14 | 14 |
15 import android.content.BroadcastReceiver; | 15 import android.content.BroadcastReceiver; |
16 import android.content.Context; | 16 import android.content.Context; |
17 import android.content.Intent; | 17 import android.content.Intent; |
18 import android.content.IntentFilter; | 18 import android.content.IntentFilter; |
| 19 import android.content.SharedPreferences; |
19 import android.content.pm.PackageManager; | 20 import android.content.pm.PackageManager; |
20 import android.media.AudioManager; | 21 import android.media.AudioManager; |
| 22 import android.preference.PreferenceManager; |
21 import android.util.Log; | 23 import android.util.Log; |
22 | 24 |
23 import java.util.Collections; | 25 import java.util.Collections; |
24 import java.util.HashSet; | 26 import java.util.HashSet; |
25 import java.util.Set; | 27 import java.util.Set; |
26 | 28 |
27 /** | 29 /** |
28 * AppRTCAudioManager manages all audio related parts of the AppRTC demo. | 30 * AppRTCAudioManager manages all audio related parts of the AppRTC demo. |
29 */ | 31 */ |
30 public class AppRTCAudioManager { | 32 public class AppRTCAudioManager { |
31 private static final String TAG = "AppRTCAudioManager"; | 33 private static final String TAG = "AppRTCAudioManager"; |
| 34 private static final String SPEAKERPHONE_AUTO = "auto"; |
| 35 private static final String SPEAKERPHONE_TRUE = "true"; |
| 36 private static final String SPEAKERPHONE_FALSE = "false"; |
32 | 37 |
33 /** | 38 /** |
34 * AudioDevice is the names of possible audio devices that we currently | 39 * AudioDevice is the names of possible audio devices that we currently |
35 * support. | 40 * support. |
36 */ | 41 */ |
37 // TODO(henrika): add support for BLUETOOTH as well. | 42 // TODO(henrika): add support for BLUETOOTH as well. |
38 public enum AudioDevice { | 43 public enum AudioDevice { |
39 SPEAKER_PHONE, | 44 SPEAKER_PHONE, |
40 WIRED_HEADSET, | 45 WIRED_HEADSET, |
41 EARPIECE, | 46 EARPIECE, |
42 } | 47 } |
43 | 48 |
44 private final Context apprtcContext; | 49 private final Context apprtcContext; |
45 private final Runnable onStateChangeListener; | 50 private final Runnable onStateChangeListener; |
46 private boolean initialized = false; | 51 private boolean initialized = false; |
47 private AudioManager audioManager; | 52 private AudioManager audioManager; |
48 private int savedAudioMode = AudioManager.MODE_INVALID; | 53 private int savedAudioMode = AudioManager.MODE_INVALID; |
49 private boolean savedIsSpeakerPhoneOn = false; | 54 private boolean savedIsSpeakerPhoneOn = false; |
50 private boolean savedIsMicrophoneMute = false; | 55 private boolean savedIsMicrophoneMute = false; |
51 | 56 |
52 // For now; always use the speaker phone as default device selection when | 57 private final AudioDevice defaultAudioDevice; |
53 // there is a choice between SPEAKER_PHONE and EARPIECE. | 58 |
54 // TODO(henrika): it is possible that EARPIECE should be preferred in some | 59 // Contains speakerphone setting: auto, true or false |
55 // cases. If so, we should set this value at construction instead. | 60 private final String useSpeakerphone; |
56 private final AudioDevice defaultAudioDevice = AudioDevice.SPEAKER_PHONE; | |
57 | 61 |
58 // Proximity sensor object. It measures the proximity of an object in cm | 62 // Proximity sensor object. It measures the proximity of an object in cm |
59 // relative to the view screen of a device and can therefore be used to | 63 // relative to the view screen of a device and can therefore be used to |
60 // assist device switching (close to ear <=> use headset earpiece if | 64 // assist device switching (close to ear <=> use headset earpiece if |
61 // available, far from ear <=> use speaker phone). | 65 // available, far from ear <=> use speaker phone). |
62 private AppRTCProximitySensor proximitySensor = null; | 66 private AppRTCProximitySensor proximitySensor = null; |
63 | 67 |
64 // Contains the currently selected audio device. | 68 // Contains the currently selected audio device. |
65 private AudioDevice selectedAudioDevice; | 69 private AudioDevice selectedAudioDevice; |
66 | 70 |
67 // 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 |
68 // avoid duplicate elements. | 72 // avoid duplicate elements. |
69 private final Set<AudioDevice> audioDevices = new HashSet<AudioDevice>(); | 73 private final Set<AudioDevice> audioDevices = new HashSet<AudioDevice>(); |
70 | 74 |
71 // Broadcast receiver for wired headset intent broadcasts. | 75 // Broadcast receiver for wired headset intent broadcasts. |
72 private BroadcastReceiver wiredHeadsetReceiver; | 76 private BroadcastReceiver wiredHeadsetReceiver; |
73 | 77 |
74 // This method is called when the proximity sensor reports a state change, | 78 // This method is called when the proximity sensor reports a state change, |
75 // e.g. from "NEAR to FAR" or from "FAR to NEAR". | 79 // e.g. from "NEAR to FAR" or from "FAR to NEAR". |
76 private void onProximitySensorChangedState() { | 80 private void onProximitySensorChangedState() { |
| 81 if (!useSpeakerphone.equals(SPEAKERPHONE_AUTO)) { |
| 82 return; |
| 83 } |
| 84 |
77 // The proximity sensor should only be activated when there are exactly two | 85 // The proximity sensor should only be activated when there are exactly two |
78 // available audio devices. | 86 // available audio devices. |
79 if (audioDevices.size() == 2 | 87 if (audioDevices.size() == 2 |
80 && audioDevices.contains(AppRTCAudioManager.AudioDevice.EARPIECE) | 88 && audioDevices.contains(AppRTCAudioManager.AudioDevice.EARPIECE) |
81 && audioDevices.contains( | 89 && audioDevices.contains( |
82 AppRTCAudioManager.AudioDevice.SPEAKER_PHONE)) { | 90 AppRTCAudioManager.AudioDevice.SPEAKER_PHONE)) { |
83 if (proximitySensor.sensorReportsNearState()) { | 91 if (proximitySensor.sensorReportsNearState()) { |
84 // Sensor reports that a "handset is being held up to a person's ear", | 92 // Sensor reports that a "handset is being held up to a person's ear", |
85 // or "something is covering the light sensor". | 93 // or "something is covering the light sensor". |
86 setAudioDevice(AppRTCAudioManager.AudioDevice.EARPIECE); | 94 setAudioDevice(AppRTCAudioManager.AudioDevice.EARPIECE); |
(...skipping 11 matching lines...) Expand all Loading... |
98 return new AppRTCAudioManager(context, deviceStateChangeListener); | 106 return new AppRTCAudioManager(context, deviceStateChangeListener); |
99 } | 107 } |
100 | 108 |
101 private AppRTCAudioManager(Context context, | 109 private AppRTCAudioManager(Context context, |
102 Runnable deviceStateChangeListener) { | 110 Runnable deviceStateChangeListener) { |
103 apprtcContext = context; | 111 apprtcContext = context; |
104 onStateChangeListener = deviceStateChangeListener; | 112 onStateChangeListener = deviceStateChangeListener; |
105 audioManager = ((AudioManager) context.getSystemService( | 113 audioManager = ((AudioManager) context.getSystemService( |
106 Context.AUDIO_SERVICE)); | 114 Context.AUDIO_SERVICE)); |
107 | 115 |
| 116 SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPref
erences(context); |
| 117 useSpeakerphone = sharedPreferences.getString(context.getString(R.string.pre
f_speakerphone_key), |
| 118 context.getString(R.string.pref_speakerphone_default)); |
| 119 |
| 120 if (useSpeakerphone.equals(SPEAKERPHONE_FALSE)) { |
| 121 defaultAudioDevice = AudioDevice.EARPIECE; |
| 122 } else { |
| 123 defaultAudioDevice = AudioDevice.SPEAKER_PHONE; |
| 124 } |
| 125 |
108 // Create and initialize the proximity sensor. | 126 // Create and initialize the proximity sensor. |
109 // Tablet devices (e.g. Nexus 7) does not support proximity sensors. | 127 // Tablet devices (e.g. Nexus 7) does not support proximity sensors. |
110 // Note that, the sensor will not be active until start() has been called. | 128 // Note that, the sensor will not be active until start() has been called. |
111 proximitySensor = AppRTCProximitySensor.create(context, new Runnable() { | 129 proximitySensor = AppRTCProximitySensor.create(context, new Runnable() { |
112 // This method will be called each time a state change is detected. | 130 // This method will be called each time a state change is detected. |
113 // Example: user holds his hand over the device (closer than ~5 cm), | 131 // Example: user holds his hand over the device (closer than ~5 cm), |
114 // or removes his hand from the device. | 132 // or removes his hand from the device. |
115 public void run() { | 133 public void run() { |
116 onProximitySensorChangedState(); | 134 onProximitySensorChangedState(); |
117 } | 135 } |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 Log.e(TAG, "Invalid device list"); | 365 Log.e(TAG, "Invalid device list"); |
348 } | 366 } |
349 | 367 |
350 if (onStateChangeListener != null) { | 368 if (onStateChangeListener != null) { |
351 // Run callback to notify a listening client. The client can then | 369 // Run callback to notify a listening client. The client can then |
352 // use public getters to query the new state. | 370 // use public getters to query the new state. |
353 onStateChangeListener.run(); | 371 onStateChangeListener.run(); |
354 } | 372 } |
355 } | 373 } |
356 } | 374 } |
OLD | NEW |