2016/5/19

MasterVolume..

framework/base/media/java/android/media/AudioService.java
    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:

沒有留言:

張貼留言