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

Commit 03b8dbcf authored by Mikhail Naganov's avatar Mikhail Naganov Committed by Android (Google) Code Review
Browse files

Merge changes from topic "cherrypicker-L47600000963081744:N22400001405878786" into udc-qpr-dev

* changes:
  audio: Improve testing of point-to-point connections
  audio: Mitigate double receiving of the "exit" command
  Audio : Add 3 VTS test cases for remote submix module
  r_submix : Fix minor issues in AIDL implementation
  Avoid sub_overflow_minimal in AIDL effects VTS
  audio: Properly support external device port with static configs
  Remove unused file EffectWorker.h
  Remove the limitation of max open streams
  audio: Make IConfig.getSurroundSound default implementation more robust
parents 4d787e55 426b8762
Loading
Loading
Loading
Loading
+9 −9
Original line number Diff line number Diff line
@@ -27,12 +27,11 @@ using aidl::android::media::audio::common::AudioHalEngineConfig;

namespace aidl::android::hardware::audio::core {
ndk::ScopedAStatus Config::getSurroundSoundConfig(SurroundSoundConfig* _aidl_return) {
    static const auto& func = __func__;
    static const SurroundSoundConfig surroundSoundConfig = [this]() {
        SurroundSoundConfig surroundCfg;
        if (mAudioPolicyConverter.getStatus() == ::android::OK) {
            surroundCfg = mAudioPolicyConverter.getSurroundSoundConfig();
        } else {
            LOG(WARNING) << __func__ << mAudioPolicyConverter.getError();
        SurroundSoundConfig surroundCfg = mAudioPolicyConverter.getSurroundSoundConfig();
        if (mAudioPolicyConverter.getStatus() != ::android::OK) {
            LOG(WARNING) << func << ": " << mAudioPolicyConverter.getError();
        }
        return surroundCfg;
    }();
@@ -42,21 +41,22 @@ ndk::ScopedAStatus Config::getSurroundSoundConfig(SurroundSoundConfig* _aidl_ret
}

ndk::ScopedAStatus Config::getEngineConfig(AudioHalEngineConfig* _aidl_return) {
    static const auto& func = __func__;
    static const AudioHalEngineConfig returnEngCfg = [this]() {
        AudioHalEngineConfig engConfig;
        if (mEngConfigConverter.getStatus() == ::android::OK) {
            engConfig = mEngConfigConverter.getAidlEngineConfig();
        } else {
            LOG(INFO) << __func__ << mEngConfigConverter.getError();
            LOG(INFO) << func << ": " << mEngConfigConverter.getError();
            if (mAudioPolicyConverter.getStatus() == ::android::OK) {
                engConfig = mAudioPolicyConverter.getAidlEngineConfig();
            } else {
                LOG(WARNING) << __func__ << mAudioPolicyConverter.getError();
                LOG(WARNING) << func << ": " << mAudioPolicyConverter.getError();
            }
        }
        // Logging full contents of the config is an overkill, just provide statistics.
        LOG(DEBUG) << "getEngineConfig: number of strategies parsed: "
                   << engConfig.productStrategies.size()
        LOG(DEBUG) << func
                   << ": number of strategies parsed: " << engConfig.productStrategies.size()
                   << ", default strategy: " << engConfig.defaultProductStrategyId
                   << ", number of volume groups parsed: " << engConfig.volumeGroups.size();
        return engConfig;
+26 −4
Original line number Diff line number Diff line
@@ -230,14 +230,14 @@ std::unique_ptr<Configuration> getPrimaryConfiguration() {

        AudioPort primaryOutMix = createPort(c.nextPortId++, "primary output",
                                             makeBitPositionFlagMask(AudioOutputFlags::PRIMARY),
                                             false, createPortMixExt(1, 1));
                                             false, createPortMixExt(0, 0));
        primaryOutMix.profiles.insert(primaryOutMix.profiles.begin(),
                                      standardPcmAudioProfiles.begin(),
                                      standardPcmAudioProfiles.end());
        c.ports.push_back(primaryOutMix);

        AudioPort primaryInMix =
                createPort(c.nextPortId++, "primary input", 0, true, createPortMixExt(1, 1));
                createPort(c.nextPortId++, "primary input", 0, true, createPortMixExt(0, 0));
        primaryInMix.profiles.push_back(
                createProfile(PcmType::INT_16_BIT,
                              {AudioChannelLayout::LAYOUT_MONO, AudioChannelLayout::LAYOUT_STEREO},
@@ -461,6 +461,10 @@ std::unique_ptr<Configuration> getUsbConfiguration() {
//    - no profiles specified
//  * "Test In", IN_AFE_PROXY
//    - no profiles specified
//  * "Wired Headset", OUT_HEADSET
//    - profile PCM 24-bit; STEREO; 48000
//  * "Wired Headset Mic", IN_HEADSET
//    - profile PCM 24-bit; MONO; 48000
//
// Mix ports:
//  * "test output", 1 max open, 1 max active stream
@@ -476,7 +480,8 @@ std::unique_ptr<Configuration> getUsbConfiguration() {
//
// Routes:
//  "test output", "test fast output", "test compressed offload" -> "Test Out"
//  "Test In" -> "test input"
//  "test output" -> "Wired Headset"
//  "Test In", "Wired Headset Mic" -> "test input"
//
// Initial port configs:
//  * "Test Out" device port: PCM 24-bit; STEREO; 48000
@@ -496,6 +501,14 @@ std::unique_ptr<Configuration> getStubConfiguration() {
                                 AudioChannelLayout::LAYOUT_STEREO, 48000, 0, false,
                                 createDeviceExt(AudioDeviceType::OUT_AFE_PROXY, 0)));

        AudioPort headsetOutDevice =
                createPort(c.nextPortId++, "Wired Headset", 0, false,
                           createDeviceExt(AudioDeviceType::OUT_HEADSET, 0,
                                           AudioDeviceDescription::CONNECTION_ANALOG));
        headsetOutDevice.profiles.push_back(
                createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_STEREO}, {48000}));
        c.ports.push_back(headsetOutDevice);

        AudioPort testInDevice = createPort(c.nextPortId++, "Test In", 0, true,
                                            createDeviceExt(AudioDeviceType::IN_AFE_PROXY, 0));
        c.ports.push_back(testInDevice);
@@ -504,6 +517,14 @@ std::unique_ptr<Configuration> getStubConfiguration() {
                                 AudioChannelLayout::LAYOUT_MONO, 48000, 0, true,
                                 createDeviceExt(AudioDeviceType::IN_AFE_PROXY, 0)));

        AudioPort headsetInDevice =
                createPort(c.nextPortId++, "Wired Headset Mic", 0, true,
                           createDeviceExt(AudioDeviceType::IN_HEADSET, 0,
                                           AudioDeviceDescription::CONNECTION_ANALOG));
        headsetInDevice.profiles.push_back(
                createProfile(PcmType::INT_24_BIT, {AudioChannelLayout::LAYOUT_MONO}, {48000}));
        c.ports.push_back(headsetInDevice);

        // Mix ports

        AudioPort testOutMix =
@@ -549,7 +570,8 @@ std::unique_ptr<Configuration> getStubConfiguration() {

        c.routes.push_back(
                createRoute({testOutMix, testFastOutMix, compressedOffloadOutMix}, testOutDevice));
        c.routes.push_back(createRoute({testInDevice}, testInMIx));
        c.routes.push_back(createRoute({testOutMix}, headsetOutDevice));
        c.routes.push_back(createRoute({testInDevice, headsetInDevice}, testInMIx));

        c.portConfigs.insert(c.portConfigs.end(), c.initialConfigs.begin(), c.initialConfigs.end());

+20 −17
Original line number Diff line number Diff line
@@ -454,16 +454,15 @@ ndk::ScopedAStatus Module::connectExternalDevice(const AudioPort& in_templateIdA
            LOG(ERROR) << __func__ << ": port id " << templateId << " is not a device port";
            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
        }
        if (!templateIt->profiles.empty()) {
            LOG(ERROR) << __func__ << ": port id " << templateId
                       << " does not have dynamic profiles";
            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
        }
        auto& templateDevicePort = templateIt->ext.get<AudioPortExt::Tag::device>();
        if (templateDevicePort.device.type.connection.empty()) {
            LOG(ERROR) << __func__ << ": port id " << templateId << " is permanently attached";
            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
        }
        if (mConnectedDevicePorts.find(templateId) != mConnectedDevicePorts.end()) {
            LOG(ERROR) << __func__ << ": port id " << templateId << " is a connected device port";
            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_ARGUMENT);
        }
        // Postpone id allocation until we ensure that there are no client errors.
        connectedPort = *templateIt;
        connectedPort.extraAudioDescriptors = in_templateIdAndAdditionalData.extraAudioDescriptors;
@@ -486,6 +485,7 @@ ndk::ScopedAStatus Module::connectExternalDevice(const AudioPort& in_templateIdA
        }
    }

    if (connectedPort.profiles.empty()) {
        if (!mDebug.simulateDeviceConnections) {
            RETURN_STATUS_IF_ERROR(populateConnectedDevicePort(&connectedPort));
        } else {
@@ -496,10 +496,13 @@ ndk::ScopedAStatus Module::connectExternalDevice(const AudioPort& in_templateIdA
            }
        }
        if (connectedPort.profiles.empty()) {
        LOG(ERROR) << "Profiles of a connected port still empty after connecting external device "
            LOG(ERROR) << __func__
                       << ": profiles of a connected port still empty after connecting external "
                          "device "
                       << connectedPort.toString();
            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
        }
    }

    for (auto profile : connectedPort.profiles) {
        if (profile.channelMasks.empty()) {
+13 −3
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@
 * limitations under the License.
 */

#include <pthread.h>

#define LOG_TAG "AHAL_Stream"
#include <android-base/logging.h>
#include <android/binder_ibinder_platform.h>
@@ -94,6 +96,14 @@ void StreamContext::reset() {
    mDataMQ.reset();
}

pid_t StreamWorkerCommonLogic::getTid() const {
#if defined(__ANDROID__)
    return pthread_gettid_np(pthread_self());
#else
    return 0;
#endif
}

std::string StreamWorkerCommonLogic::init() {
    if (mContext->getCommandMQ() == nullptr) return "Command MQ is null";
    if (mContext->getReplyMQ() == nullptr) return "Reply MQ is null";
@@ -164,7 +174,7 @@ StreamInWorkerLogic::Status StreamInWorkerLogic::cycle() {
    switch (command.getTag()) {
        case Tag::halReservedExit:
            if (const int32_t cookie = command.get<Tag::halReservedExit>();
                cookie == mContext->getInternalCommandCookie()) {
                cookie == (mContext->getInternalCommandCookie() ^ getTid())) {
                mDriver->shutdown();
                setClosed();
                // This is an internal command, no need to reply.
@@ -384,7 +394,7 @@ StreamOutWorkerLogic::Status StreamOutWorkerLogic::cycle() {
    switch (command.getTag()) {
        case Tag::halReservedExit:
            if (const int32_t cookie = command.get<Tag::halReservedExit>();
                cookie == mContext->getInternalCommandCookie()) {
                cookie == (mContext->getInternalCommandCookie() ^ getTid())) {
                mDriver->shutdown();
                setClosed();
                // This is an internal command, no need to reply.
@@ -717,7 +727,7 @@ void StreamCommonImpl::stopWorker() {
    if (auto commandMQ = mContext.getCommandMQ(); commandMQ != nullptr) {
        LOG(DEBUG) << __func__ << ": asking the worker to exit...";
        auto cmd = StreamDescriptor::Command::make<StreamDescriptor::Command::Tag::halReservedExit>(
                mContext.getInternalCommandCookie());
                mContext.getInternalCommandCookie() ^ mWorker->getTid());
        // Note: never call 'pause' and 'resume' methods of StreamWorker
        // in the HAL implementation. These methods are to be used by
        // the client side only. Preventing the worker loop from running
+1 −0
Original line number Diff line number Diff line
@@ -223,6 +223,7 @@ class StreamWorkerCommonLogic : public ::android::hardware::audio::common::Strea
        : mContext(context),
          mDriver(driver),
          mTransientStateDelayMs(context->getTransientStateDelayMs()) {}
    pid_t getTid() const;
    std::string init() override;
    void populateReply(StreamDescriptor::Reply* reply, bool isConnected) const;
    void populateReplyWrongState(StreamDescriptor::Reply* reply,
Loading