其他分享
首页 > 其他分享> > Android Audio代码分析(2): AudioPoilicyService

Android Audio代码分析(2): AudioPoilicyService

作者:互联网

AudioPolicyService 所在进程

frameworks/av/media/audioserver
➜  audioserver git:(0111) ✗ tree
.
├── Android.mk
├── audioserver.rc
├── main_audioserver.cpp
└── OWNERS

int main(int argc __unused, char **argv)
{
        android::hardware::configureRpcThreadpool(4, false /*callerWillJoin*/);
        sp<ProcessState> proc(ProcessState::self());
        sp<IServiceManager> sm = defaultServiceManager();
        ALOGI("ServiceManager: %p", sm.get());

        AudioFlinger::instantiate();
        ALOGI("ServiceManager: AudioFlinger instantiate done %p", sm.get());

        AudioPolicyService::instantiate();
        ALOGI("ServiceManager: AudioPolicyService instantiate done %p", sm.get());

        instantiateVRAudioServer();
        ALOGI("ServiceManager: VRAudioServer instantiate done %p", sm.get());

        ALOGI("ServiceManager: done %p", sm.get());
        ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
}

AudioPolicyService::instantiate()

就这么一句话包含了整个AudioPolicyService的初始化

在 class AudioPolicyService中没有找到instantiate(),看基类BinderService
template<typename SERVICE>
class BinderService
{
public:
    static status_t publish(bool allowIsolated = false,
                            int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {
        sp<IServiceManager> sm(defaultServiceManager());
        return sm->addService(String16(SERVICE::getServiceName()),

                                                new SERVICE(),                   

                                                allowIsolated, dumpFlags);
    }

    static void instantiate() { publish(); }
};

new SERVICE() -> new AudioPolicyService()

AudioPolicyService()

BinderService::instantiate 调用到 new AudioPolicyService()

触发对象的创建和初次使用AudioPolicyService() and AudioPolicyService::onFirstRef()

AudioPolicyService::AudioPolicyService()
    : BnAudioPolicyService(), //构造函数
      mAudioPolicyManager(NULL), //变量初始化
      mAudioPolicyClient(NULL),
      mPhoneState(AUDIO_MODE_INVALID),
      mCaptureStateNotifier(false) {
}

void AudioPolicyService::onFirstRef()
{
    {
        // start audio commands thread
        mAudioCommandThread = new AudioCommandThread(String8("ApmAudio"), this);
        // start output activity command thread
        mOutputCommandThread = new AudioCommandThread(String8("ApmOutput"), this);

        mAudioPolicyClient = new AudioPolicyClient(this);
        mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);
    }
    // load audio processing modules
    sp<AudioPolicyEffects> audioPolicyEffects = new AudioPolicyEffects();

    sp<UidPolicy> uidPolicy = new UidPolicy(this);
    uidPolicy->registerSelf();
}

AudioCommandThread

 

AudioCommandThread: 哪里有对user permission的判断?
// Thread used to send audio config commands to audio flinger
// For audio config commands, it is necessary because audio flinger requires that the calling
// process (user) has permission to modify audio settings.
class AudioCommandThread : public Thread {}

AudioPolicyClient

class AudioPolicyClient : public AudioPolicyClientInterface

构造函数很简单

AudioPolicyClient(AudioPolicyService *service) : mAudioPolicyService(service) {}

AudioPolicyManager

mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);

大部分工作是这个函数完成的,在详细分析该函数之前先看下AudioPolicyInterface 和 AudioPolicyClientInterface

IAudioPolicyService  AudioPolicyInterface  AudioPolicyClientInterface

这三个接口有些函数比较相似,看上去比较乱。IAudioPolicyService是向外提供的接口,其他两个接口是服务它的, AudioPoliocyInterface是平台无关或者说是它会去调用平台相关的AudioPolicyClientInterface, AudioPolicyClientInterface会调用AudioFlinger service 去执行策略。

// The AudioPolicyInterface and AudioPolicyClientInterface classes define the communication interfaces
// between the platform specific audio policy manager and Android generic audio policy manager.
// The platform specific audio policy manager must implement methods of the AudioPolicyInterface class.
// This implementation makes use of the AudioPolicyClientInterface to control the activity and
// configuration of audio input and output streams.

// The platform specific audio policy manager is in charge of the audio routing and volume control
// policies for a given platform.
// The main roles of this module are:
[1] - keep track of current system state (removable device connections, phone state, user requests...).
//   System state changes and user actions are notified to audio policy manager with methods of the AudioPolicyInterface.

[2]   - process getOutput() queries received when AudioTrack objects are created: Those queries
//   return a handler on an output that has been selected, configured and opened by the audio policy manager and that
//   must be used by the AudioTrack when registering to the AudioFlinger with the createTrack() method.
//   When the AudioTrack object is released, a putOutput() query is received and the audio policy manager can decide
//   to close or reconfigure the output depending on other streams using this output and current system state.

[3]   - similarly process getInput() and putInput() queries received from AudioRecord objects and configure audio inputs.

[4]   - process volume control requests: the stream volume is converted from an index value (received from UI) to a float value
//   applicable to each output as a function of platform specific settings and current output route (destination device). It
//   also make sure that streams are not muted if not allowed (e.g. camera shutter sound in some countries).
//

AudioPolicyManager (APM)

AudioPolicyManager implements audio policy manager behavior common to all platforms
class AudioPolicyManager : public AudioPolicyInterface, public AudioPolicyManagerObserver
{}

mAudioPolicyManager = createAudioPolicyManager(mAudioPolicyClient);

frameworks/av/services/audiopolicy/manager/AudioPolicyFactory.cpp
extern "C" AudioPolicyInterface* createAudioPolicyManager(
        AudioPolicyClientInterface *clientInterface)
{
    AudioPolicyManager *apm = new AudioPolicyManager(clientInterface);
    status_t status = apm->initialize();
    if (status != NO_ERROR) {
        delete apm;
        apm = nullptr;
    }
    return apm;
}

// These methods should be used when finer control over APM initialization
// is needed, e.g. in tests. Must be used in conjunction with the constructor
// that only performs fields initialization. The public constructor comprises
// these steps in the following sequence:
//   - field initializing constructor;
//   - loadConfig;
//   - initialize.

createAudioPolicyManager分为两部分:

1. new AudioPolicyManager(AudioPolicyClientInterface)

2. apm->initialize()

new AudioPolicyManager(clientInterface)

这里构造函数有两个:一个参数、两个参数,但最关键的函数还是 loadConfig()

AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface)
        : AudioPolicyManager(clientInterface, false /*forTesting*/)
{
    loadConfig();
}


AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterface,
                                       bool /*forTesting*/)
    :
    mUidCached(AID_AUDIOSERVER), // no need to call getuid(), there's only one of us running.
    mpClientInterface(clientInterface),
    mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
    mA2dpSuspended(false),
    mConfig(mHwModulesAll, mOutputDevicesAll, mInputDevicesAll, mDefaultOutputDevice),
    mAudioPortGeneration(1),
    mEnableAudioLoopback(false),
    mIsCERegion(false),
    mBeaconMuteRefCount(0),
    mBeaconPlayingRefCount(0),
    mBeaconMuted(false),     
    mTtsOutputAvailable(false),
    mMasterMono(false),
    mMusicEffectOutput(AUDIO_IO_HANDLE_NONE)
{
}

loadConfig()

audio_policy_configuration.xml的格式

audio_policy_configuration.xml
    <!-- Modules section:
        There is one section per audio HW module present on the platform.
        Each module section will contains two mandatory tags for audio HAL “halVersion” and “name”.
        The module names are the same as in current .conf file:
                “primary”, “A2DP”, “remote_submix”, “USB”
        Each module will contain the following sections:
        “devicePorts”: a list of device descriptors for all input and output devices accessible via this
        module.
        This contains both permanently attached devices and removable devices.
        “mixPorts”: listing all output and input streams exposed by the audio HAL

         (HAL 不导出devicePorts?)
        “routes”: list of possible connections between input and output devices or between stream                          and devices.
            "route": is defined by an attribute:
                -"type": <mux|mix> means all sources are mutual exclusive (mux) or can be mixed (mix)
                -"sink": the sink involved in this route
                -"sources": all the sources than can be connected to the sink via vis route
        “attachedDevices”: permanently attached devices.
        The attachedDevices section is a list of devices names. The names correspond to device names
        defined in <devicePorts> section.
        “defaultOutputDevice”: device to be used by default when no policy rule applies
    -->

deserializeAudioPolicyXmlConfig解析配置文件

deserializeAudioPolicyXmlConfig(AudioPolicyConfig &config) ->
        deserializeAudioPolicyFile(audioPolicyXmlConfigFile,  //"audio_policy_configuration.xml"

                        &config); 

frameworks/av/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp

status_t deserializeAudioPolicyFile(const char *fileName, AudioPolicyConfig *config)
{
    PolicySerializer serializer;
    return serializer.deserialize(fileName, config);
}

template<typename E, typename C>
struct AndroidCollectionTraits {
    typedef sp<E> Element;
    typedef C Collection;
    typedef void* PtrSerializingCtx;

    static status_t addElementToCollection(const Element &element, Collection *collection) {
        return collection->add(element) >= 0 ? NO_ERROR : BAD_VALUE;
    }
};

// A profile section contains a name,  one audio format and the list of supported sampling rates
// and channel masks for this format
struct AudioProfileTraits : public AndroidCollectionTraits<AudioProfile, AudioProfileVector>
{
    static constexpr const char *tag = "profile";
    static constexpr const char *collectionTag = "profiles";

    struct Attributes
    {
        static constexpr const char *samplingRates = "samplingRates";
        static constexpr const char *format = "format";
        static constexpr const char *channelMasks = "channelMasks";
    };

    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
};


struct MixPortTraits : public AndroidCollectionTraits<IOProfile, IOProfileCollection>
{
    static constexpr const char *tag = "mixPort";
    static constexpr const char *collectionTag = "mixPorts";

    struct Attributes
    {
        static constexpr const char *name = "name";
        static constexpr const char *role = "role";
        static constexpr const char *roleSource = "source"; /**< <attribute role source value>. */
        static constexpr const char *flags = "flags";
        static constexpr const char *maxOpenCount = "maxOpenCount";
        static constexpr const char *maxActiveCount = "maxActiveCount";
    };

    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
    // Children: GainTraits
};

struct DevicePortTraits : public AndroidCollectionTraits<DeviceDescriptor, DeviceVector>
{
    static constexpr const char *tag = "devicePort";
    static constexpr const char *collectionTag = "devicePorts";

    struct Attributes
    {
        /**  <device tag name>: any string without space. */
        static constexpr const char *tagName = "tagName";
        static constexpr const char *type = "type"; /**< <device type>. */
        static constexpr const char *role = "role"; /**< <device role: sink or source>. */
        static constexpr const char *roleSource = "source"; /**< <attribute role source value>. */
        /** optional: device address, char string less than 64. */
        static constexpr const char *address = "address";
        /** optional: the list of encoded audio formats that are known to be supported. */
        static constexpr const char *encodedFormats = "encodedFormats";
    };

    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
    // Children: GainTraits (optional)
};


struct RouteTraits : public AndroidCollectionTraits<AudioRoute, AudioRouteVector>
{
    static constexpr const char *tag = "route";
    static constexpr const char *collectionTag = "routes";

    struct Attributes
    {
        static constexpr const char *type = "type"; /**< <route type>: mix or mux. */
        static constexpr const char *typeMix = "mix"; /**< type attribute mix value. */
        static constexpr const char *sink = "sink"; /**< <sink: involved in this route>. */
        /** sources: all source that can be involved in this route. */
        static constexpr const char *sources = "sources";
    };

    typedef HwModule *PtrSerializingCtx;

    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
};

struct ModuleTraits : public AndroidCollectionTraits<HwModule, HwModuleCollection>
{
    static constexpr const char *tag = "module";
    static constexpr const char *collectionTag = "modules";

    static constexpr const char *childAttachedDevicesTag = "attachedDevices";
    static constexpr const char *childAttachedDeviceTag = "item";
    static constexpr const char *childDefaultOutputDeviceTag = "defaultOutputDevice";

    struct Attributes
    {
        static constexpr const char *name = "name";
        static constexpr const char *version = "halVersion";
    };

    typedef AudioPolicyConfig *PtrSerializingCtx;

    static Return<Element> deserialize(const xmlNode *cur, PtrSerializingCtx serializingContext);
    // Children: mixPortTraits, devicePortTraits, and routeTraits
    // Need to call deserialize on each child
};

每个xxxTraints都有自己的deserialize 函数

Return<ModuleTraits::Element> ModuleTraits::deserialize(const xmlNode *cur, PtrSerializingCtx ctx)
{
1]: <module name="primary" halVersion="2.0">
    std::string name = getXmlAttribute(cur, Attributes::name);

    uint32_t versionMajor = 0, versionMinor = 0;
    std::string versionLiteral = getXmlAttribute(cur, Attributes::version);
    if (!versionLiteral.empty()) {
        sscanf(versionLiteral.c_str(), "%u.%u", &versionMajor, &versionMinor);
    }

    Element module = new HwModule(name.c_str(), versionMajor, versionMinor);


    // Deserialize childrens: Audio Mix Port, Audio Device Ports (Source/Sink), Audio Routes

2]: <mixPorts>
    MixPortTraits::Collection mixPorts;
    status_t status = deserializeCollection<MixPortTraits>(cur, &mixPorts, NULL);
    if (status != NO_ERROR) {
        return Status::fromStatusT(status);
    }
    module->setProfiles(mixPorts); // class HwModule -> addProfile-> addOut/InputProfile: 
                                   // mOut/InputProfiles.add(profile) and mPorts.add(profile)
                   
3]: <devicePorts>
    DevicePortTraits::Collection devicePorts;
    status = deserializeCollection<DevicePortTraits>(cur, &devicePorts, NULL);
    if (status != NO_ERROR) {
        return Status::fromStatusT(status);
    }
    module->setDeclaredDevices(devicePorts); // mDeclaredDevices = devices; mPorts.add(device[i])

4]: <routes>
    RouteTraits::Collection routes;
    status = deserializeCollection<RouteTraits>(cur, &routes, module.get());
    if (status != NO_ERROR) {
        return Status::fromStatusT(status);
    }
    module->setRoutes(routes);

5]: attachedDevices
     sp<DeviceDescriptor> device = module->getDeclaredDevices().
                                getDeviceFromTagName(std::string(reinterpret_cast<const char*>(
                                                        attachedDevice.get())));
     ctx->addDevice(device); // ctx指的是 class AudioPolicyConfig

6]: defaultOutputDevice
    sp<DeviceDescriptor> device = module->getDeclaredDevices().getDeviceFromTagName(
                        std::string(reinterpret_cast<const char*>(defaultOutputDevice.get())));
    ctx->setDefaultOutputDevice(device);
}
 

标签:status,audio,const,AudioPoilicyService,char,constexpr,static,Android,Audio
来源: https://blog.csdn.net/u011279649/article/details/119424935