Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c38de55a authored by Automerger Merge Worker's avatar Automerger Merge Worker
Browse files

Allow for late audio module discovery in APM am: c0d04987 am: b278b3e0

Change-Id: I62c5e5526b49ba98363c1ef043cc55ee3f3787bb
parents b182ef58 b278b3e0
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -83,6 +83,10 @@ public:
    // configuration functions
    //

    // Informs APM that new HAL modules are available. This typically happens
    // due to registration of an audio HAL service.
    virtual void onNewAudioModulesAvailable() = 0;

    // indicate a change in device connection status
    virtual status_t setDeviceConnectionState(audio_devices_t device,
                                              audio_policy_dev_state_t state,
+21 −23
Original line number Diff line number Diff line
@@ -37,13 +37,13 @@ class AudioPolicyConfig
{
public:
    AudioPolicyConfig(HwModuleCollection &hwModules,
                      DeviceVector &availableOutputDevices,
                      DeviceVector &availableInputDevices,
                      DeviceVector &outputDevices,
                      DeviceVector &inputDevices,
                      sp<DeviceDescriptor> &defaultOutputDevice)
        : mEngineLibraryNameSuffix(kDefaultEngineLibraryNameSuffix),
          mHwModules(hwModules),
          mAvailableOutputDevices(availableOutputDevices),
          mAvailableInputDevices(availableInputDevices),
          mOutputDevices(outputDevices),
          mInputDevices(inputDevices),
          mDefaultOutputDevice(defaultOutputDevice),
          mIsSpeakerDrcEnabled(false),
          mIsCallScreenModeSupported(false)
@@ -70,23 +70,23 @@ public:
        mHwModules = hwModules;
    }

    void addAvailableDevice(const sp<DeviceDescriptor> &availableDevice)
    void addDevice(const sp<DeviceDescriptor> &device)
    {
        if (audio_is_output_device(availableDevice->type())) {
            mAvailableOutputDevices.add(availableDevice);
        } else if (audio_is_input_device(availableDevice->type())) {
            mAvailableInputDevices.add(availableDevice);
        if (audio_is_output_device(device->type())) {
            mOutputDevices.add(device);
        } else if (audio_is_input_device(device->type())) {
            mInputDevices.add(device);
        }
    }

    void addAvailableInputDevices(const DeviceVector &availableInputDevices)
    void addInputDevices(const DeviceVector &inputDevices)
    {
        mAvailableInputDevices.add(availableInputDevices);
        mInputDevices.add(inputDevices);
    }

    void addAvailableOutputDevices(const DeviceVector &availableOutputDevices)
    void addOutputDevices(const DeviceVector &outputDevices)
    {
        mAvailableOutputDevices.add(availableOutputDevices);
        mOutputDevices.add(outputDevices);
    }

    bool isSpeakerDrcEnabled() const { return mIsSpeakerDrcEnabled; }
@@ -106,14 +106,14 @@ public:

    const HwModuleCollection getHwModules() const { return mHwModules; }

    const DeviceVector &getAvailableInputDevices() const
    const DeviceVector &getInputDevices() const
    {
        return mAvailableInputDevices;
        return mInputDevices;
    }

    const DeviceVector &getAvailableOutputDevices() const
    const DeviceVector &getOutputDevices() const
    {
        return mAvailableOutputDevices;
        return mOutputDevices;
    }

    void setDefaultOutputDevice(const sp<DeviceDescriptor> &defaultDevice)
@@ -134,13 +134,11 @@ public:
        sp<AudioProfile> micProfile = new AudioProfile(
                AUDIO_FORMAT_PCM_16_BIT, AUDIO_CHANNEL_IN_MONO, 8000);
        defaultInputDevice->addAudioProfile(micProfile);
        mAvailableOutputDevices.add(mDefaultOutputDevice);
        mAvailableInputDevices.add(defaultInputDevice);
        mOutputDevices.add(mDefaultOutputDevice);
        mInputDevices.add(defaultInputDevice);

        sp<HwModule> module = new HwModule(AUDIO_HARDWARE_MODULE_ID_PRIMARY, 2 /*halVersionMajor*/);
        mHwModules.add(module);
        mDefaultOutputDevice->attach(module);
        defaultInputDevice->attach(module);

        sp<OutputProfile> outProfile = new OutputProfile("primary");
        outProfile->addAudioProfile(
@@ -191,8 +189,8 @@ private:
    std::string mSource;
    std::string mEngineLibraryNameSuffix;
    HwModuleCollection &mHwModules; /**< Collection of Module, with Profiles, i.e. Mix Ports. */
    DeviceVector &mAvailableOutputDevices;
    DeviceVector &mAvailableInputDevices;
    DeviceVector &mOutputDevices;
    DeviceVector &mInputDevices;
    sp<DeviceDescriptor> &mDefaultOutputDevice;
    // TODO: remove when legacy conf file is removed. true on devices that use DRC on the
    // DEVICE_CATEGORY_SPEAKER path to boost soft sounds, used to adjust volume curves accordingly.
+1 −1
Original line number Diff line number Diff line
@@ -653,7 +653,7 @@ Return<ModuleTraits::Element> ModuleTraits::deserialize(const xmlNode *cur, PtrS
                        sp<DeviceDescriptor> device = module->getDeclaredDevices().
                                getDeviceFromTagName(std::string(reinterpret_cast<const char*>(
                                                        attachedDevice.get())));
                        ctx->addAvailableDevice(device);
                        ctx->addDevice(device);
                    }
                }
            }
+69 −73
Original line number Diff line number Diff line
@@ -4397,7 +4397,7 @@ AudioPolicyManager::AudioPolicyManager(AudioPolicyClientInterface *clientInterfa
    mpClientInterface(clientInterface),
    mLimitRingtoneVolume(false), mLastVoiceVolume(-1.0f),
    mA2dpSuspended(false),
    mConfig(mHwModulesAll, mAvailableOutputDevices, mAvailableInputDevices, mDefaultOutputDevice),
    mConfig(mHwModulesAll, mOutputDevicesAll, mInputDevicesAll, mDefaultOutputDevice),
    mAudioPortGeneration(1),
    mBeaconMuteRefCount(0),
    mBeaconPlayingRefCount(0),
@@ -4442,9 +4442,69 @@ status_t AudioPolicyManager::initialize() {
        return status;
    }

    // mAvailableOutputDevices and mAvailableInputDevices now contain all attached devices
    // after parsing the config, mOutputDevicesAll and mInputDevicesAll contain all known devices;
    // open all output streams needed to access attached devices
    onNewAudioModulesAvailable();

    // make sure default device is reachable
    if (mDefaultOutputDevice == 0 || !mAvailableOutputDevices.contains(mDefaultOutputDevice)) {
        ALOGE_IF(mDefaultOutputDevice != 0, "Default device %s is unreachable",
                 mDefaultOutputDevice->toString().c_str());
        status = NO_INIT;
    }
    // If microphones address is empty, set it according to device type
    for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
        if (mAvailableInputDevices[i]->address().empty()) {
            if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
                mAvailableInputDevices[i]->setAddress(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
            } else if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
                mAvailableInputDevices[i]->setAddress(AUDIO_BACK_MICROPHONE_ADDRESS);
            }
        }
    }

    if (mPrimaryOutput == 0) {
        ALOGE("Failed to open primary output");
        status = NO_INIT;
    }

    // Silence ALOGV statements
    property_set("log.tag." LOG_TAG, "D");

    updateDevicesAndOutputs();
    return status;
}

AudioPolicyManager::~AudioPolicyManager()
{
   for (size_t i = 0; i < mOutputs.size(); i++) {
        mOutputs.valueAt(i)->close();
   }
   for (size_t i = 0; i < mInputs.size(); i++) {
        mInputs.valueAt(i)->close();
   }
   mAvailableOutputDevices.clear();
   mAvailableInputDevices.clear();
   mOutputs.clear();
   mInputs.clear();
   mHwModules.clear();
   mHwModulesAll.clear();
   mManualSurroundFormats.clear();
}

status_t AudioPolicyManager::initCheck()
{
    return hasPrimaryOutput() ? NO_ERROR : NO_INIT;
}

// ---

void AudioPolicyManager::onNewAudioModulesAvailable()
{
    for (const auto& hwModule : mHwModulesAll) {
        if (std::find(mHwModules.begin(), mHwModules.end(), hwModule) != mHwModules.end()) {
            continue;
        }
        hwModule->setHandle(mpClientInterface->loadHwModule(hwModule->getName()));
        if (hwModule->getHandle() == AUDIO_MODULE_HANDLE_NONE) {
            ALOGW("could not open HW module %s", hwModule->getName());
@@ -4473,7 +4533,7 @@ status_t AudioPolicyManager::initialize() {
                continue;
            }
            const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
            DeviceVector availProfileDevices = supportedDevices.filter(mAvailableOutputDevices);
            DeviceVector availProfileDevices = supportedDevices.filter(mOutputDevicesAll);
            sp<DeviceDescriptor> supportedDevice = 0;
            if (supportedDevices.contains(mDefaultOutputDevice)) {
                supportedDevice = mDefaultOutputDevice;
@@ -4485,7 +4545,7 @@ status_t AudioPolicyManager::initialize() {
                }
                supportedDevice = availProfileDevices.itemAt(0);
            }
            if (!mAvailableOutputDevices.contains(supportedDevice)) {
            if (!mOutputDevicesAll.contains(supportedDevice)) {
                continue;
            }
            sp<SwAudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(outProfile,
@@ -4503,6 +4563,8 @@ status_t AudioPolicyManager::initialize() {
                // give a valid ID to an attached device once confirmed it is reachable
                if (!device->isAttached()) {
                    device->attach(hwModule);
                    mAvailableOutputDevices.add(device);
                    setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
                }
            }
            if (mPrimaryOutput == 0 &&
@@ -4531,7 +4593,7 @@ status_t AudioPolicyManager::initialize() {
            // chose first device present in profile's SupportedDevices also part of
            // available input devices
            const DeviceVector &supportedDevices = inProfile->getSupportedDevices();
            DeviceVector availProfileDevices = supportedDevices.filter(mAvailableInputDevices);
            DeviceVector availProfileDevices = supportedDevices.filter(mInputDevicesAll);
            if (availProfileDevices.isEmpty()) {
                ALOGE("%s: Input device list is empty!", __FUNCTION__);
                continue;
@@ -4556,81 +4618,15 @@ status_t AudioPolicyManager::initialize() {
                if (!device->isAttached()) {
                    device->attach(hwModule);
                    device->importAudioPortAndPickAudioProfile(inProfile, true);
                }
            }
            inputDesc->close();
        }
    }
    // make sure all attached devices have been allocated a unique ID
    auto checkAndSetAvailable = [this](auto& devices) {
        for (size_t i = 0; i < devices.size();) {
            const auto &device = devices[i];
            if (!device->isAttached()) {
                ALOGW("device %s is unreachable", device->toString().c_str());
                devices.remove(device);
                continue;
            }
            // Device is now validated and can be appended to the available devices of the engine
                    mAvailableInputDevices.add(device);
                    setEngineDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
            i++;
        }
    };
    checkAndSetAvailable(mAvailableOutputDevices);
    checkAndSetAvailable(mAvailableInputDevices);

    // make sure default device is reachable
    if (mDefaultOutputDevice == 0 || !mAvailableOutputDevices.contains(mDefaultOutputDevice)) {
        ALOGE_IF(mDefaultOutputDevice != 0, "Default device %s is unreachable",
                 mDefaultOutputDevice->toString().c_str());
        status = NO_INIT;
                }
    // If microphones address is empty, set it according to device type
    for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
        if (mAvailableInputDevices[i]->address().empty()) {
            if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
                mAvailableInputDevices[i]->setAddress(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
            } else if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
                mAvailableInputDevices[i]->setAddress(AUDIO_BACK_MICROPHONE_ADDRESS);
            }
        }
    }

    if (mPrimaryOutput == 0) {
        ALOGE("Failed to open primary output");
        status = NO_INIT;
            }

    // Silence ALOGV statements
    property_set("log.tag." LOG_TAG, "D");

    updateDevicesAndOutputs();
    return status;
}

AudioPolicyManager::~AudioPolicyManager()
{
   for (size_t i = 0; i < mOutputs.size(); i++) {
        mOutputs.valueAt(i)->close();
   }
   for (size_t i = 0; i < mInputs.size(); i++) {
        mInputs.valueAt(i)->close();
            inputDesc->close();
        }
   mAvailableOutputDevices.clear();
   mAvailableInputDevices.clear();
   mOutputs.clear();
   mInputs.clear();
   mHwModules.clear();
   mHwModulesAll.clear();
   mManualSurroundFormats.clear();
    }

status_t AudioPolicyManager::initCheck()
{
    return hasPrimaryOutput() ? NO_ERROR : NO_INIT;
}

// ---

void AudioPolicyManager::addOutput(audio_io_handle_t output,
                                   const sp<SwAudioOutputDescriptor>& outputDesc)
{
+6 −3
Original line number Diff line number Diff line
@@ -325,6 +325,8 @@ public:

        bool isCallScreenModeSupported() override;

        void onNewAudioModulesAvailable() override;

        status_t initialize();

protected:
@@ -729,6 +731,8 @@ protected:
        SwAudioOutputCollection mPreviousOutputs;
        AudioInputCollection mInputs;     // list of input descriptors

        DeviceVector  mOutputDevicesAll; // all output devices from the config
        DeviceVector  mInputDevicesAll;  // all input devices from the config
        DeviceVector  mAvailableOutputDevices; // all available output devices
        DeviceVector  mAvailableInputDevices;  // all available input devices

@@ -739,9 +743,8 @@ protected:

        EffectDescriptorCollection mEffects;  // list of registered audio effects
        sp<DeviceDescriptor> mDefaultOutputDevice; // output device selected by default at boot time
        HwModuleCollection mHwModules; // contains only modules that have been loaded successfully
        HwModuleCollection mHwModulesAll; // normally not needed, used during construction and for
                                          // dumps
        HwModuleCollection mHwModules; // contains modules that have been loaded successfully
        HwModuleCollection mHwModulesAll; // contains all modules declared in the config

        AudioPolicyConfig mConfig;

Loading