Android:Mstar平台 HDMI OUT 静音流程

时间:2022-06-14 06:13:39

一、framework层

  1. APP调用 AudioManager 的 adjustStreamVolume() 接口实现在: frameworksbaseservicescorejavacomandroidserveraudioAudioService.java

    在判断当前是系统静音操作时,调用 HdmiOutAudioMute Native接口:

            if (isMuteAdjust) {
                boolean state;
                if (direction == AudioManager.ADJUST_TOGGLE_MUTE) {
                    state = !streamState.mIsMuted;
                } else {
                    state = direction == AudioManager.ADJUST_MUTE;
                }
                if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
                    setSystemAudioMute(state);
                    /*lxl 20191206 add patch begin*/
                    PowerManagerService.nativeSetHdmiOutAudioMute(state);
                    /*lxl 20191130 add patch end*/
                }
                for (int stream = 0; stream < mStreamStates.length; stream  ) {
                    if (streamTypeAlias == mStreamVolumeAlias[stream]) {
                        if (!(readCameraSoundForced()
                                    && (mStreamStates[stream].getStreamType()
                                        == AudioSystem.STREAM_SYSTEM_ENFORCED))) {
                            mStreamStates[stream].mute(state);
                        }
                    }
                }
            }

  2. nativeSetHdmiOutAudioMute 接口声明在: frameworksbaseservicescorejavacomandroidserverpowerPowerManagerService.java

public static native boolean nativeSetHdmiOutAudioMute(boolean onOff);

 

二、Native层

  1.frameworksbaseservicescorejnicom_android_server_power_PowerManagerService.cpp 中实现了 nativeSetHdmiOutAudioMute() 方法:

static jboolean nativeSetHdmiOutAudioMute(JNIEnv *env, jclass clazz, jboolean onOff){
    std::lock_guard<std::mutex> lock(gPowerHalMutex);
    if (getInputHal()) {
        Return<bool> ret = gInputHal->setHdmiOutAudioMute(onOff);
        if (!ret.isOk()) {
            ALOGE("Failed to SetHdmiOutAudioMute.");
            return false;
        }
        return ret;
    }
    ALOGE("Failed to SetHdmiOutAudioMute input hal is null.");
    return false;
}

  Native方法的声明和注册:

static const JNINativeMethod gPowerManagerServiceMethods[] = {
    /* name, signature, funcPtr */
  ......
    {"nativeSetHdmiOutAudioMute", "(Z)Z",
            (void*) nativeSetHdmiOutAudioMute },
  ......
}
int register_android_server_PowerManagerService(JNIEnv* env) {
    int res = jniRegisterNativeMethods(env, "com/android/server/power/PowerManagerService",
            gPowerManagerServiceMethods, NELEM(gPowerManagerServiceMethods));
    (void) res;  // Faked use when LOG_NDEBUG.
    LOG_FATAL_IF(res < 0, "Unable to register native methods.");

    // Callbacks

    jclass clazz;
    FIND_CLASS(clazz, "com/android/server/power/PowerManagerService");

    GET_METHOD_ID(gPowerManagerServiceClassInfo.userActivityFromNative, clazz,
            "userActivityFromNative", "(JII)V");

    // Initialize
    for (int i = 0; i <= USER_ACTIVITY_EVENT_LAST; i  ) {
        gLastEventTime[i] = LLONG_MIN;
    }
    gPowerManagerServiceObj = NULL;
    return 0;
}

  2. 上面 gInputHal->setHdmiOutAudioMute(onOff); 调用是通过HIDL调用HAL层接口, Service的获取:

bool getInputHal(){
    if (gInputHal == nullptr){
        gInputHal = IMstarTvInput::getService();
        if (gInputHal == nullptr) {
            ALOGD("Load input HAL service fail");
            return -1;
        }    
    }

    return gInputHal != nullptr;
}

 

三、HAL层

  1 HIDL接口定义 vendormstarhardwareinterfacestvinput1.0IMstarTvInput.hal,继承于 TvInput :

interface IMstarTvInput
    extends [email protected]1.0::ITvInput {
     @callflow(next="*")
         //EpgManager function(31/32)
    ...
    setHdmiOutAudioMute(bool bEnable)
          generates (bool result);
    ...
}

  2. 接口的定义 vendormstarhardwareinterfacestvinput1.0defaultTvInput.h, TvInput 又继承于 IMstarTvInput :

struct TvInput : public IMstarTvInput {
    TvInput(mstar_tv_input_device_t* device);
    ~TvInput();
    /*mstar tv interface*/
...
    Return<bool> setHdmiOutAudioMute(bool bEnable);
...
}

  3. 具体的方法实现在 vendormstarhardwareinterfacestvinput1.0defaultTvInput_TvManager.cpp

Return<bool> TvInput::setHdmiOutAudioMute(bool bEnable){
    return mDevice->TvManager_dev->setHdmiOutAudioMute(bEnable);
}

  4. 其中 mDevice->TvManager_dev->setHdmiOutAudioMute() 方法的定义在:vendormstarhardwareinterfacestvinput1.0defaultmstarTvInput_TvManager_dev.h

#ifndef MSTAR_TV_INPUT_TvManager_H
#define MSTAR_TV_INPUT_TvManager_H
#include <mstar/hardware/tv/input/1.0/ITvManagerType.h>
#include "tvmanager/TvManager.h"
using ::mstar::hardware::tv::input::V1_0::ITvManagerType;
typedef struct mstar_TvManager_dev {
    ......
    bool (*setHdmiOutAudioMute)(bool bEnable);
    ......
}

  5. 其方法实现在 vendormstarhardwaretv_inputmstar_tv_input_TvManager.cpp

bool mstar_tv_input_TvManager::setHdmiOutAudioMute(bool bEnable){
    return g_pTvManagerImpl->setHdmiOutAudioMute(bEnable);
}

   g_pTvManagerImpl 是通过 TvManager 转换所得:

void mstar_tv_input_TvManager::registerTvManagerInstance(sp<TvManager> &ptr) {
    g_pTvManagerImpl=ptr;
}

  6. TvManager 的接口定义在 vendormstarcommonlibrariestvapihidl_wrappertvmanagerTvManager.h

class TvManager : virtual public RefBase
{
public:
    TvManager();
    ~TvManager();

    static sp<TvManager> connect();
    void HIDLconnect();
    static void disconnect();

    status_t setListener(const sp<TvManagerListener>& listener);

    ...
    static bool setHdmiOutAudioMute(bool bEnable);
    ...

}

  7. 方法实现在 vendormstarsupernovaprojectstvostvmanagerlibtvmanagerTvManager.cpp:

bool TvManager::setHdmiOutAudioMute(bool bOnOff)
{
    ALOGV("TvManager setHdmiOutAudioMuten");
    return getITvManager()->setHdmiOutAudioMute(bOnOff);
}

  后面就跳跃到 mstar 的 supernova 层。

 

四、Supernova层

  1. TvManager 的 setHdmiOutAudioMute 实现在 vendormstarsupernovaprojectstvostvmanagerlibtvmanagerservice

bool TvManagerService::Client::setHdmiOutAudioMute(bool bOnOff){
    TVOS_API_ESTIMATE_START()
    TVOS_API_ESTIMATE_START(LOCK)
    Mutex::Autolock lock(m_FuncLock);
    TVOS_API_ESTIMATE_END(LOCK)
    ALOGV("TvManagerService::Client::setHdmiOutAudioMuten");
    
    bool ret = FALSE;

    ret = MSrv_Control::GetInstance()->setHdmiOutAudioMute(bOnOff);

    TVOS_API_ESTIMATE_END()
    return ret;
}

  2. 最终方法实现在vendormstarsupernovaprojectstvostvmanagerlibtvmanagerserviceTvManagerService.cpp,后面便是通过I2C接口对HDMI控制器的操作。

BOOL MSrv_Control_common::setHdmiOutMute(const BOOL bOnOff)
{
    if(MDrv_NT68411_Exist())
    {
        if(bOnOff == FALSE)
        {
            MDrv_NT68411_Write(NT68411_SUBCMD_HDMI_MUTE, HDMI_MUTE_OFF);
        }
        else
        {
            MDrv_NT68411_Write(NT68411_SUBCMD_HDMI_MUTE, HDMI_MUTE_ON);
        }
    }
    return TRUE;
}