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

Commit 681e98a0 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes from topic "cp-aosp-2647304" into udc-qpr-dev

* changes:
  audio: Add DriverInterface::start method
  Audio : Add remote submix stream implementation
parents 6f07dabb 19d08c00
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ cc_defaults {
        "libbinder_ndk",
        "libcutils",
        "libfmq",
        "libnbaio_mono",
        "libstagefright_foundation",
        "libtinyalsav2",
        "libutils",
@@ -76,6 +77,10 @@ cc_library {
        "Stream.cpp",
        "StreamStub.cpp",
        "Telephony.cpp",
        "r_submix/ModuleRemoteSubmix.cpp",
        "r_submix/RemoteSubmixUtils.cpp",
        "r_submix/SubmixRoute.cpp",
        "r_submix/StreamRemoteSubmix.cpp",
        "usb/ModuleUsb.cpp",
        "usb/StreamUsb.cpp",
        "usb/UsbAlsaMixerControl.cpp",
+16 −3
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@

#include "core-impl/Bluetooth.h"
#include "core-impl/Module.h"
#include "core-impl/ModuleRemoteSubmix.h"
#include "core-impl/ModuleUsb.h"
#include "core-impl/SoundDose.h"
#include "core-impl/StreamStub.h"
@@ -111,8 +112,9 @@ std::shared_ptr<Module> Module::createInstance(Type type) {
    switch (type) {
        case Module::Type::USB:
            return ndk::SharedRefBase::make<ModuleUsb>(type);
        case Type::DEFAULT:
        case Type::R_SUBMIX:
            return ndk::SharedRefBase::make<ModuleRemoteSubmix>(type);
        case Type::DEFAULT:
        default:
            return ndk::SharedRefBase::make<Module>(type);
    }
@@ -181,8 +183,8 @@ ndk::ScopedAStatus Module::createStreamContext(
        StreamContext temp(
                std::make_unique<StreamContext::CommandMQ>(1, true /*configureEventFlagWord*/),
                std::make_unique<StreamContext::ReplyMQ>(1, true /*configureEventFlagWord*/),
                portConfigIt->format.value(), portConfigIt->channelMask.value(),
                portConfigIt->sampleRate.value().value, flags,
                portConfigIt->portId, portConfigIt->format.value(),
                portConfigIt->channelMask.value(), portConfigIt->sampleRate.value().value, flags,
                portConfigIt->ext.get<AudioPortExt::mix>().handle,
                std::make_unique<StreamContext::DataMQ>(frameSize * in_bufferSizeFrames),
                asyncCallback, outEventCallback, params);
@@ -490,6 +492,17 @@ ndk::ScopedAStatus Module::connectExternalDevice(const AudioPort& in_templateIdA
        return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
    }

    for (auto profile : connectedPort.profiles) {
        if (profile.channelMasks.empty()) {
            LOG(ERROR) << __func__ << ": the profile " << profile.name << " has no channel masks";
            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
        }
        if (profile.sampleRates.empty()) {
            LOG(ERROR) << __func__ << ": the profile " << profile.name << " has no sample rates";
            return ndk::ScopedAStatus::fromExceptionCode(EX_ILLEGAL_STATE);
        }
    }

    connectedPort.id = ++getConfig().nextPortId;
    auto [connectedPortsIt, _] =
            mConnectedDevicePorts.insert(std::pair(connectedPort.id, std::vector<int32_t>()));
+27 −12
Original line number Diff line number Diff line
@@ -166,10 +166,15 @@ StreamInWorkerLogic::Status StreamInWorkerLogic::cycle() {
        case Tag::start:
            if (mState == StreamDescriptor::State::STANDBY ||
                mState == StreamDescriptor::State::DRAINING) {
                if (::android::status_t status = mDriver->start(); status == ::android::OK) {
                    populateReply(&reply, mIsConnected);
                    mState = mState == StreamDescriptor::State::STANDBY
                                     ? StreamDescriptor::State::IDLE
                                     : StreamDescriptor::State::ACTIVE;
                } else {
                    LOG(ERROR) << __func__ << ": start failed: " << status;
                    mState = StreamDescriptor::State::ERROR;
                }
            } else {
                populateReplyWrongState(&reply, command);
            }
@@ -377,26 +382,36 @@ StreamOutWorkerLogic::Status StreamOutWorkerLogic::cycle() {
            populateReply(&reply, mIsConnected);
            break;
        case Tag::start: {
            bool commandAccepted = true;
            std::optional<StreamDescriptor::State> nextState;
            switch (mState) {
                case StreamDescriptor::State::STANDBY:
                    mState = StreamDescriptor::State::IDLE;
                    nextState = StreamDescriptor::State::IDLE;
                    break;
                case StreamDescriptor::State::PAUSED:
                    mState = StreamDescriptor::State::ACTIVE;
                    nextState = StreamDescriptor::State::ACTIVE;
                    break;
                case StreamDescriptor::State::DRAIN_PAUSED:
                    switchToTransientState(StreamDescriptor::State::DRAINING);
                    nextState = StreamDescriptor::State::DRAINING;
                    break;
                case StreamDescriptor::State::TRANSFER_PAUSED:
                    switchToTransientState(StreamDescriptor::State::TRANSFERRING);
                    nextState = StreamDescriptor::State::TRANSFERRING;
                    break;
                default:
                    populateReplyWrongState(&reply, command);
                    commandAccepted = false;
            }
            if (commandAccepted) {
            if (nextState.has_value()) {
                if (::android::status_t status = mDriver->start(); status == ::android::OK) {
                    populateReply(&reply, mIsConnected);
                    if (*nextState == StreamDescriptor::State::IDLE ||
                        *nextState == StreamDescriptor::State::ACTIVE) {
                        mState = *nextState;
                    } else {
                        switchToTransientState(*nextState);
                    }
                } else {
                    LOG(ERROR) << __func__ << ": start failed: " << status;
                    mState = StreamDescriptor::State::ERROR;
                }
            }
        } break;
        case Tag::burst:
+39 −8
Original line number Diff line number Diff line
@@ -33,33 +33,67 @@ namespace aidl::android::hardware::audio::core {

StreamStub::StreamStub(const Metadata& metadata, StreamContext&& context)
    : StreamCommonImpl(metadata, std::move(context)),
      mFrameSizeBytes(context.getFrameSize()),
      mSampleRate(context.getSampleRate()),
      mIsAsynchronous(!!context.getAsyncCallback()),
      mFrameSizeBytes(getContext().getFrameSize()),
      mSampleRate(getContext().getSampleRate()),
      mIsAsynchronous(!!getContext().getAsyncCallback()),
      mIsInput(isInput(metadata)) {}

::android::status_t StreamStub::init() {
    mIsInitialized = true;
    usleep(500);
    return ::android::OK;
}

::android::status_t StreamStub::drain(StreamDescriptor::DrainMode) {
    if (!mIsInitialized) {
        LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
    }
    usleep(500);
    return ::android::OK;
}

::android::status_t StreamStub::flush() {
    if (!mIsInitialized) {
        LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
    }
    usleep(500);
    return ::android::OK;
}

::android::status_t StreamStub::pause() {
    if (!mIsInitialized) {
        LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
    }
    usleep(500);
    return ::android::OK;
}

::android::status_t StreamStub::standby() {
    if (!mIsInitialized) {
        LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
    }
    usleep(500);
    mIsStandby = true;
    return ::android::OK;
}

::android::status_t StreamStub::start() {
    if (!mIsInitialized) {
        LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
    }
    usleep(500);
    mIsStandby = false;
    return ::android::OK;
}

::android::status_t StreamStub::transfer(void* buffer, size_t frameCount, size_t* actualFrameCount,
                                         int32_t* latencyMs) {
    if (!mIsInitialized) {
        LOG(FATAL) << __func__ << ": must not happen for an uninitialized driver";
    }
    if (mIsStandby) {
        LOG(FATAL) << __func__ << ": must not happen while in standby";
    }
    static constexpr float kMicrosPerSecond = MICROS_PER_SECOND;
    static constexpr float kScaleFactor = .8f;
    if (mIsAsynchronous) {
@@ -80,13 +114,10 @@ StreamStub::StreamStub(const Metadata& metadata, StreamContext&& context)
    return ::android::OK;
}

::android::status_t StreamStub::standby() {
    usleep(500);
    return ::android::OK;
void StreamStub::shutdown() {
    mIsInitialized = false;
}

void StreamStub::shutdown() {}

StreamInStub::StreamInStub(const SinkMetadata& sinkMetadata, StreamContext&& context,
                           const std::vector<MicrophoneInfo>& microphones)
    : StreamStub(sinkMetadata, std::move(context)), StreamIn(microphones) {}
+59 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include "core-impl/Module.h"

namespace aidl::android::hardware::audio::core {

class ModuleRemoteSubmix : public Module {
  public:
    explicit ModuleRemoteSubmix(Module::Type type) : Module(type) {}

  private:
    // IModule interfaces
    ndk::ScopedAStatus getTelephony(std::shared_ptr<ITelephony>* _aidl_return) override;
    ndk::ScopedAStatus getBluetooth(std::shared_ptr<IBluetooth>* _aidl_return) override;
    ndk::ScopedAStatus getMicMute(bool* _aidl_return) override;
    ndk::ScopedAStatus setMicMute(bool in_mute) override;

    // Module interfaces
    ndk::ScopedAStatus createInputStream(
            const ::aidl::android::hardware::audio::common::SinkMetadata& sinkMetadata,
            StreamContext&& context,
            const std::vector<::aidl::android::media::audio::common::MicrophoneInfo>& microphones,
            std::shared_ptr<StreamIn>* result) override;
    ndk::ScopedAStatus createOutputStream(
            const ::aidl::android::hardware::audio::common::SourceMetadata& sourceMetadata,
            StreamContext&& context,
            const std::optional<::aidl::android::media::audio::common::AudioOffloadInfo>&
                    offloadInfo,
            std::shared_ptr<StreamOut>* result) override;
    ndk::ScopedAStatus populateConnectedDevicePort(
            ::aidl::android::media::audio::common::AudioPort* audioPort) override;
    ndk::ScopedAStatus checkAudioPatchEndpointsMatch(
            const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sources,
            const std::vector<::aidl::android::media::audio::common::AudioPortConfig*>& sinks)
            override;
    void onExternalDeviceConnectionChanged(
            const ::aidl::android::media::audio::common::AudioPort& audioPort,
            bool connected) override;
    ndk::ScopedAStatus onMasterMuteChanged(bool mute) override;
    ndk::ScopedAStatus onMasterVolumeChanged(float volume) override;
};

}  // namespace aidl::android::hardware::audio::core
Loading