summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorJohn Grossman <johngro@google.com>2012-07-20 14:51:35 -0700
committerJohn Grossman <johngro@google.com>2012-08-08 11:28:15 -0700
commitd8f178d613821c3f61a5c5e391eb275339e526a9 (patch)
tree93038d06c70535eeebc364e9f86cedbec074802c /services
parent3478eaa23c19dbbe473be70e8f3cc0c904d2465c (diff)
downloadframeworks_av-d8f178d613821c3f61a5c5e391eb275339e526a9.zip
frameworks_av-d8f178d613821c3f61a5c5e391eb275339e526a9.tar.gz
frameworks_av-d8f178d613821c3f61a5c5e391eb275339e526a9.tar.bz2
Change audio flinger to user HAL master mute if available
(cherry picked from commit 91de9b56282d126ffb36344266af5fee3cefcfdd) > Change audio flinger to user HAL master mute if available > > Hand merge from ics-aah > > > Change audio flinger to user HAL master mute if available: DO NOT MERGE > > > > Replicate the pattern used for HAL master volume support to make use > > of master mute support if the HAL supports it. This is part of the > > change needed to address bug 6828363. Because of the divergences > > between ICS and master, this change will need to be merged by hand. > > > > Signed-off-by: John Grossman <johngro@google.com> > > Change-Id: I6d83be524021d273d093bcb117b8f2fe57c23685 > > Change-Id: I32280582905c969aaec2bb166ec5c61df82d737a > Signed-off-by: John Grossman <johngro@google.com> Change-Id: I5cd709187221d307fe25c5117ccaadca5f6b197b Signed-off-by: John Grossman <johngro@google.com>
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/AudioFlinger.cpp95
-rw-r--r--services/audioflinger/AudioFlinger.h30
2 files changed, 115 insertions, 10 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index d65a2b6..41ae70e 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -219,6 +219,8 @@ AudioFlinger::AudioFlinger()
mMasterVolumeSW(1.0f),
mMasterVolumeSupportLvl(MVS_NONE),
mMasterMute(false),
+ mMasterMuteSW(false),
+ mMasterMuteSupportLvl(MMS_NONE),
mNextUniqueId(1),
mMode(AUDIO_MODE_INVALID),
mBtNrecIsOff(false)
@@ -699,16 +701,40 @@ bool AudioFlinger::getMicMute() const
status_t AudioFlinger::setMasterMute(bool muted)
{
+ status_t ret = initCheck();
+ if (ret != NO_ERROR) {
+ return ret;
+ }
+
// check calling permissions
if (!settingsAllowed()) {
return PERMISSION_DENIED;
}
+ bool swmm = muted;
+
+ // when hw supports master mute, don't mute in sw mixer
+ if (MMS_NONE != mMasterMuteSupportLvl) {
+ for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
+ AutoMutex lock(mHardwareLock);
+ audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
+
+ mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
+ if (NULL != dev->set_master_mute) {
+ dev->set_master_mute(dev, muted);
+ }
+ mHardwareStatus = AUDIO_HW_IDLE;
+ }
+
+ swmm = false;
+ }
+
Mutex::Autolock _l(mLock);
// This is an optimization, so PlaybackThread doesn't have to look at the one from AudioFlinger
- mMasterMute = muted;
+ mMasterMute = muted;
+ mMasterMuteSW = swmm;
for (size_t i = 0; i < mPlaybackThreads.size(); i++)
- mPlaybackThreads.valueAt(i)->setMasterMute(muted);
+ mPlaybackThreads.valueAt(i)->setMasterMute(swmm);
return NO_ERROR;
}
@@ -731,6 +757,12 @@ bool AudioFlinger::masterMute() const
return masterMute_l();
}
+bool AudioFlinger::masterMuteSW() const
+{
+ Mutex::Autolock _l(mLock);
+ return masterMuteSW_l();
+}
+
float AudioFlinger::masterVolume_l() const
{
if (MVS_FULL == mMasterVolumeSupportLvl) {
@@ -750,6 +782,24 @@ float AudioFlinger::masterVolume_l() const
return mMasterVolume;
}
+bool AudioFlinger::masterMute_l() const
+{
+ if (MMS_FULL == mMasterMuteSupportLvl) {
+ bool ret_val;
+ AutoMutex lock(mHardwareLock);
+
+ mHardwareStatus = AUDIO_HW_GET_MASTER_MUTE;
+ assert(NULL != mPrimaryHardwareDev);
+ assert(NULL != mPrimaryHardwareDev->get_master_mute);
+
+ mPrimaryHardwareDev->get_master_mute(mPrimaryHardwareDev, &ret_val);
+ mHardwareStatus = AUDIO_HW_IDLE;
+ return ret_val;
+ }
+
+ return mMasterMute;
+}
+
status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value,
audio_io_handle_t output)
{
@@ -1503,7 +1553,7 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge
mMixBuffer(NULL), mSuspended(0), mBytesWritten(0),
// Assumes constructor is called by AudioFlinger with it's mLock held,
// but it would be safer to explicitly pass initial masterMute as parameter
- mMasterMute(audioFlinger->masterMute_l()),
+ mMasterMute(audioFlinger->masterMuteSW_l()),
// mStreamTypes[] initialized in constructor body
mOutput(output),
// Assumes constructor is called by AudioFlinger with it's mLock held,
@@ -6863,10 +6913,13 @@ audio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,
mHardwareStatus = AUDIO_HW_SET_MODE;
outHwDev->set_mode(outHwDev, mMode);
- // Determine the level of master volume support the primary audio HAL has,
- // and set the initial master volume at the same time.
+ // Determine the level of master volume/master mute support the primary
+ // audio HAL has, and set the initial master volume/mute state at the same
+ // time.
float initialVolume = 1.0;
+ bool initialMute = false;
mMasterVolumeSupportLvl = MVS_NONE;
+ mMasterMuteSupportLvl = MMS_NONE;
mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME;
if ((NULL != outHwDev->get_master_volume) &&
@@ -6882,20 +6935,44 @@ audio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,
(NO_ERROR != outHwDev->set_master_volume(outHwDev, initialVolume))) {
mMasterVolumeSupportLvl = MVS_NONE;
}
- // now that we have a primary device, initialize master volume on other devices
+
+ mHardwareStatus = AUDIO_HW_GET_MASTER_MUTE;
+ if ((NULL != outHwDev->get_master_mute) &&
+ (NO_ERROR == outHwDev->get_master_mute(outHwDev, &initialMute))) {
+ mMasterMuteSupportLvl = MMS_FULL;
+ } else {
+ mMasterMuteSupportLvl = MMS_SETONLY;
+ initialMute = 0;
+ }
+
+ mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
+ if ((NULL == outHwDev->set_master_mute) ||
+ (NO_ERROR != outHwDev->set_master_mute(outHwDev, initialMute))) {
+ mMasterMuteSupportLvl = MMS_NONE;
+ }
+
+ // now that we have a primary device, initialize master volume/mute
+ // on other devices
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
audio_hw_device_t *dev = mAudioHwDevs.valueAt(i)->hwDevice();
if ((dev != mPrimaryHardwareDev) &&
(NULL != dev->set_master_volume)) {
+ mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
dev->set_master_volume(dev, initialVolume);
}
+
+ if (NULL != dev->set_master_mute) {
+ mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE;
+ dev->set_master_mute(dev, initialMute);
+ }
}
+
mHardwareStatus = AUDIO_HW_IDLE;
- mMasterVolumeSW = (MVS_NONE == mMasterVolumeSupportLvl)
- ? initialVolume
- : 1.0;
+ mMasterVolumeSW = initialVolume;
mMasterVolume = initialVolume;
+ mMasterMuteSW = initialMute;
+ mMasterMute = initialMute;
}
return id;
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 2b6d00f..1bef42c 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -124,6 +124,7 @@ public:
virtual float masterVolume() const;
virtual float masterVolumeSW() const;
virtual bool masterMute() const;
+ virtual bool masterMuteSW() const;
virtual status_t setStreamVolume(audio_stream_type_t stream, float value,
audio_io_handle_t output);
@@ -1911,6 +1912,27 @@ mutable Mutex mLock; // mutex for process, commands and handl
MVS_FULL,
};
+ enum master_mute_support {
+ // MMS_NONE:
+ // Audio HAL has no support for master mute, either setting or getting.
+ // All master mute control must be implemented in SW by the
+ // AudioFlinger mixing core.
+ MMS_NONE,
+
+ // MMS_SETONLY:
+ // Audio HAL has support for setting master mute, but not for getting
+ // master mute. AudioFlinger needs to keep track of the last set
+ // master mute in addition to needing to set an initial, default,
+ // master mute at HAL load time.
+ MMS_SETONLY,
+
+ // MMS_FULL:
+ // Audio HAL has support both for setting and getting master mute.
+ // AudioFlinger should send all set and get master mute requests
+ // directly to the HAL.
+ MMS_FULL,
+ };
+
class AudioHwDevice {
public:
AudioHwDevice(const char *moduleName, audio_hw_device_t *hwDevice) :
@@ -1957,6 +1979,8 @@ mutable Mutex mLock; // mutex for process, commands and handl
AUDIO_HW_GET_INPUT_BUFFER_SIZE, // get_input_buffer_size
AUDIO_HW_GET_MASTER_VOLUME, // get_master_volume
AUDIO_HW_GET_PARAMETER, // get_parameters
+ AUDIO_HW_SET_MASTER_MUTE, // set_master_mute
+ AUDIO_HW_GET_MASTER_MUTE, // get_master_mute
};
mutable hardware_call_state mHardwareStatus; // for dump only
@@ -1969,7 +1993,10 @@ mutable Mutex mLock; // mutex for process, commands and handl
float mMasterVolume;
float mMasterVolumeSW;
master_volume_support mMasterVolumeSupportLvl;
+
bool mMasterMute;
+ bool mMasterMuteSW;
+ master_mute_support mMasterMuteSupportLvl;
DefaultKeyedVector< audio_io_handle_t, sp<RecordThread> > mRecordThreads;
@@ -1983,7 +2010,8 @@ mutable Mutex mLock; // mutex for process, commands and handl
float masterVolume_l() const;
float masterVolumeSW_l() const { return mMasterVolumeSW; }
- bool masterMute_l() const { return mMasterMute; }
+ bool masterMute_l() const;
+ bool masterMuteSW_l() const { return mMasterMuteSW; }
audio_module_handle_t loadHwModule_l(const char *name);
Vector < sp<SyncEvent> > mPendingSyncEvents; // sync events awaiting for a session