summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPawit Pornkitprasan <p.pawit@gmail.com>2011-09-01 22:39:48 +0700
committerPawit Pornkitprasan <p.pawit@gmail.com>2011-09-02 17:06:24 +0700
commit14513e1c14b88d7bee4596a14425ae6d7f76640d (patch)
tree4f7c4e4a7ca472273fba9148296bd7635be164b8
parent81732be0729544209c80615129411a45a50bd90e (diff)
downloaddevice_samsung_aries-common-14513e1c14b88d7bee4596a14425ae6d7f76640d.zip
device_samsung_aries-common-14513e1c14b88d7bee4596a14425ae6d7f76640d.tar.gz
device_samsung_aries-common-14513e1c14b88d7bee4596a14425ae6d7f76640d.tar.bz2
libaudio: Fix FM Radio to work with other android sounds
- Run openPcmOut_l and openMixer_l regardless if whether they are already initialized or not. (These functions have a open counter and they will be closed prematurely if we don't declare that we are going to use them.) - Fix invalid output device after playing notification - Fix resuming FM radio after call ended Note: resuming FM radio after notification is also dependent on a patch to FM.apk Change-Id: I8ab9fe74bb5a099252e0c1072a40e86209bc4a05
-rw-r--r--libaudio/AudioHardware.cpp106
-rw-r--r--libaudio/AudioHardware.h3
2 files changed, 71 insertions, 38 deletions
diff --git a/libaudio/AudioHardware.cpp b/libaudio/AudioHardware.cpp
index c2efbd1..8d0daeb 100644
--- a/libaudio/AudioHardware.cpp
+++ b/libaudio/AudioHardware.cpp
@@ -98,6 +98,7 @@ AudioHardware::AudioHardware() :
mActivatedCP(false),
#ifdef HAVE_FM_RADIO
mFmFd(-1),
+ mFmResumeAfterCall(false),
#endif
mDriverOp(DRV_NONE)
{
@@ -435,6 +436,12 @@ status_t AudioHardware::setMode(int mode)
spOut->unlock();
}
+ if (mFmResumeAfterCall) {
+ mFmResumeAfterCall = false;
+
+ enableFMRadio();
+ }
+
return status;
}
@@ -520,50 +527,14 @@ status_t AudioHardware::setParameters(const String8& keyValuePairs)
// fm radio on
key = String8(AudioParameter::keyFmOn);
if (param.get(key, value) == NO_ERROR) {
- LOGV("AudioHardware::setParameters() Turning FM Radio ON");
- if (mMixer == NULL) {
- openPcmOut_l();
- openMixer_l();
- setInputSource_l(AUDIO_SOURCE_DEFAULT);
- }
- if (mMixer != NULL) {
- LOGV("AudioHardware::setParameters() FM Radio is ON, calling setFMRadioPath_l()");
- setFMRadioPath_l(mOutput->device());
- }
-
- if (mFmFd < 0) {
- mFmFd = open("/dev/radio0", O_RDWR);
- }
+ enableFMRadio();
}
param.remove(key);
// fm radio off
key = String8(AudioParameter::keyFmOff);
if (param.get(key, value) == NO_ERROR) {
- LOGV("AudioHardware::setParameters() Turning FM Radio OFF");
-
- if (mMixer != NULL) {
- // Disable FM radio flag to allow the codec to be turned off
- // (the flag is automatically set by the kernel driver when FM is enabled)
- // No need to turn off the FM Radio path as the kernel driver will handle that
- TRACE_DRIVER_IN(DRV_MIXER_GET)
- struct mixer_ctl *ctl = mixer_get_control(mMixer, "Codec Status", 0);
- TRACE_DRIVER_OUT
-
- if (ctl != NULL) {
- TRACE_DRIVER_IN(DRV_MIXER_SEL)
- mixer_ctl_select(ctl, "FMR_FLAG_CLEAR");
- TRACE_DRIVER_OUT
- }
-
- closeMixer_l();
- closePcmOut_l();
- }
-
- if (mFmFd > 0) {
- close(mFmFd);
- mFmFd = -1;
- }
+ disableFMRadio();
}
param.remove(key);
#endif
@@ -817,6 +788,56 @@ status_t AudioHardware::setIncallPath_l(uint32_t device)
}
#ifdef HAVE_FM_RADIO
+void AudioHardware::enableFMRadio() {
+ LOGV("AudioHardware::enableFMRadio() Turning FM Radio ON");
+
+ if (mMode == AudioSystem::MODE_IN_CALL) {
+ LOGV("AudioHardware::enableFMRadio() Call is active. Delaying FM enable.");
+ mFmResumeAfterCall = true;
+ }
+ else {
+ openPcmOut_l();
+ openMixer_l();
+ setInputSource_l(AUDIO_SOURCE_DEFAULT);
+
+ if (mMixer != NULL) {
+ LOGV("AudioHardware::enableFMRadio() FM Radio is ON, calling setFMRadioPath_l()");
+ setFMRadioPath_l(mOutput->device());
+ }
+
+ if (mFmFd < 0) {
+ mFmFd = open("/dev/radio0", O_RDWR);
+ }
+ }
+}
+
+void AudioHardware::disableFMRadio() {
+ LOGV("AudioHardware::disableFMRadio() Turning FM Radio OFF");
+
+ if (mMixer != NULL) {
+ // Disable FM radio flag to allow the codec to be turned off
+ // (the flag is automatically set by the kernel driver when FM is enabled)
+ // No need to turn off the FM Radio path as the kernel driver will handle that
+ TRACE_DRIVER_IN(DRV_MIXER_GET)
+ struct mixer_ctl *ctl = mixer_get_control(mMixer, "Codec Status", 0);
+ TRACE_DRIVER_OUT
+
+ if (ctl != NULL) {
+ TRACE_DRIVER_IN(DRV_MIXER_SEL)
+ mixer_ctl_select(ctl, "FMR_FLAG_CLEAR");
+ TRACE_DRIVER_OUT
+ }
+
+ closeMixer_l();
+ closePcmOut_l();
+ }
+
+ if (mFmFd > 0) {
+ close(mFmFd);
+ mFmFd = -1;
+ }
+}
+
status_t AudioHardware::setFMRadioPath_l(uint32_t device)
{
LOGV("setFMRadioPath_l() device %x", device);
@@ -824,6 +845,15 @@ status_t AudioHardware::setFMRadioPath_l(uint32_t device)
AudioPath path;
const char *fmpath;
+ if (device != AudioSystem::DEVICE_OUT_SPEAKER && (device & AudioSystem::DEVICE_OUT_SPEAKER) != 0) {
+ /* Fix the case where we're on headset and the system has just played a
+ * notification sound to both the speaker and the headset. The device
+ * now is an ORed value and we need to get back its original value.
+ */
+ device -= AudioSystem::DEVICE_OUT_SPEAKER;
+ LOGD("setFMRadioPath_l() device removed speaker %x", device);
+ }
+
switch(device){
case AudioSystem::DEVICE_OUT_SPEAKER:
LOGD("setFMRadioPath_l() fmradio speaker route");
diff --git a/libaudio/AudioHardware.h b/libaudio/AudioHardware.h
index b50e273..2a1f6c7 100644
--- a/libaudio/AudioHardware.h
+++ b/libaudio/AudioHardware.h
@@ -121,6 +121,8 @@ public:
status_t setIncallPath_l(uint32_t device);
#ifdef HAVE_FM_RADIO
+ void enableFMRadio();
+ void disableFMRadio();
status_t setFMRadioPath_l(uint32_t device);
#endif
@@ -182,6 +184,7 @@ private:
#ifdef HAVE_FM_RADIO
int mFmFd;
+ bool mFmResumeAfterCall;
#endif
// trace driver operations for dump