public void setMasterVolume(int volume, int flags, String callingPackage) { if (mUseFixedVolume) { return; } if (mAppOps.noteOp(AppOpsManager.OP_AUDIO_MASTER_VOLUME, Binder.getCallingUid(), callingPackage) != AppOpsManager.MODE_ALLOWED) { return; } if (volume < 0) { volume = 0; } else if (volume > MAX_MASTER_VOLUME) { volume = MAX_MASTER_VOLUME; } doSetMasterVolume((float)volume / MAX_MASTER_VOLUME, flags); } private void doSetMasterVolume(float volume, int flags) { // don't allow changing master volume when muted if (!AudioSystem.getMasterMute()) { int oldVolume = getMasterVolume(); AudioSystem.setMasterVolume(volume); int newVolume = getMasterVolume(); if (newVolume != oldVolume) { // Post a persist master volume msg sendMsg(mAudioHandler, MSG_PERSIST_MASTER_VOLUME, SENDMSG_REPLACE, Math.round(volume * (float)1000.0), 0, null, PERSIST_DELAY); } // Send the volume update regardless whether there was a change. sendMasterVolumeUpdate(flags, oldVolume, newVolume); } }
最後call 到 framework/av/service/audioflinger/AudioFlinger.cpp
status_t AudioFlinger::setMasterVolume(float value) { .... ... // Set master volume in the HALs which support it. for (size_t i = 0; i < mAudioHwDevs.size(); i++) { AutoMutex lock(mHardwareLock); AudioHwDevice *dev = mAudioHwDevs.valueAt(i); mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME; if (dev->canSetMasterVolume()) { dev->hwDevice()->set_master_volume(dev->hwDevice(), value); } mHardwareStatus = AUDIO_HW_IDLE; }
所以 AudioHwDevice 要 implement canSetMasterVolume( ), 然後實做 set_master_volume( )
再查 canSetMasterVolume..
一樣,在 AudioFlinger.h:
class AudioHwDevice { ... ... bool canSetMasterVolume() const { return (0 != (mFlags & AHWD_CAN_SET_MASTER_VOLUME)); }
mFlag 是在 AudioHwDevice 生成時給定的...
AudioHwDevice(audio_module_handle_t handle, const char *moduleName, audio_hw_device_t *hwDevice, Flags flags) : mHandle(handle), mModuleName(strdup(moduleName)) , mHwDevice(hwDevice) , mFlags(flags) { }
同樣的地方...
audioflinger 在 load audio.xxx.xxx module 時,會測試 audio module 是否有 implement set_master_volume( )
好決定生成 AudioHwDevice 時,flag 要不要加上 AHWD_CAN_SET_MASTER_VOLUME:
AudioHwDevice::Flags flags = static_cast<AudioHwDevice::Flags>(0); { .... .... mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME; if ((NULL != dev->set_master_volume) && (OK == dev->set_master_volume(dev, mMasterVolume))) { flags = static_cast<AudioHwDevice::Flags>(flags | AudioHwDevice::AHWD_CAN_SET_MASTER_VOLUME); } mHardwareStatus = AUDIO_HW_SET_MASTER_MUTE; if ((NULL != dev->set_master_mute) && (OK == dev->set_master_mute(dev, mMasterMute))) { flags = static_cast<AudioHwDevice::Flags>(flags | AudioHwDevice::AHWD_CAN_SET_MASTER_MUTE); } ... } ... audio_module_handle_t handle = nextUniqueId(); mAudioHwDevs.add(handle, new AudioHwDevice(handle, name, dev, flags));
然後在 hw_module 的 source (imx6): hardware/imx/alsa/tinyalsa_hal.c:
static int adev_open(const hw_module_t* module, const char* name, hw_device_t** device) { .... adev->hw_device.set_master_volume = adev_set_master_volume;
有 module function table 的 assign,
implement 是:
static int adev_set_master_volume(struct audio_hw_device *dev, float volume) { return -ENOSYS; }.. 也就是說...沒有提供這個功能。
所以把 return value 從 -ENOSYS 改成 0
然後,還要改...
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 8006659..ecb8780 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -65,7 +65,7 @@ <!-- Flag indicating that the media framework should allow changing master volume stream and nothing else . --> - <bool name="config_useMasterVolume">false</bool> + <bool name="config_useMasterVolume">true</bool>叫 ..
./media/java/android/media/AudioManager.java:585: com.android.internal.R.bool.config_useMasterVolume); ./media/java/android/media/AudioService.java:641: com.android.internal.R.bool.config_useMasterVolume);這兩個 source 用 MasterVolume
另外 UI:
沒有留言:
張貼留言