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

Commit 222535c3 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add support for getting all available microphones characteristics."

parents 343cd9e0 46a76fa5
Loading
Loading
Loading
Loading
+249 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 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.
 */

#ifndef ANDROID_MICROPHONE_INFO_H
#define ANDROID_MICROPHONE_INFO_H

#include <binder/Parcel.h>
#include <binder/Parcelable.h>
#include <system/audio.h>
#include <utils/String16.h>
#include <utils/Vector.h>

namespace android {
namespace media {

#define RETURN_IF_FAILED(calledOnce)                                     \
    {                                                                    \
        status_t returnStatus = calledOnce;                              \
        if (returnStatus) {                                              \
            ALOGE("Failed at %s:%d (%s)", __FILE__, __LINE__, __func__); \
            return returnStatus;                                         \
         }                                                               \
    }

class MicrophoneInfo : public Parcelable {
public:
    MicrophoneInfo() = default;
    MicrophoneInfo(const MicrophoneInfo& microphoneInfo) = default;
    MicrophoneInfo(audio_microphone_characteristic_t& characteristic) {
        mDeviceId = String16(&characteristic.device_id[0]);
        mPortId = characteristic.id;
        mType = characteristic.type;
        mAddress = String16(&characteristic.address[0]);
        mDeviceLocation = characteristic.location;
        mDeviceGroup = characteristic.group;
        mIndexInTheGroup = characteristic.index_in_the_group;
        mGeometricLocation.push_back(characteristic.geometric_location.x);
        mGeometricLocation.push_back(characteristic.geometric_location.y);
        mGeometricLocation.push_back(characteristic.geometric_location.z);
        mOrientation.push_back(characteristic.orientation.x);
        mOrientation.push_back(characteristic.orientation.y);
        mOrientation.push_back(characteristic.orientation.z);
        Vector<float> frequencies;
        Vector<float> responses;
        for (size_t i = 0; i < characteristic.num_frequency_responses; i++) {
            frequencies.push_back(characteristic.frequency_responses[0][i]);
            responses.push_back(characteristic.frequency_responses[1][i]);
        }
        mFrequencyResponses.push_back(frequencies);
        mFrequencyResponses.push_back(responses);
        for (size_t i = 0; i < AUDIO_CHANNEL_COUNT_MAX; i++) {
            mChannelMapping.push_back(characteristic.channel_mapping[i]);
        }
        mSensitivity = characteristic.sensitivity;
        mMaxSpl = characteristic.max_spl;
        mMinSpl = characteristic.min_spl;
        mDirectionality = characteristic.directionality;
    }

    virtual ~MicrophoneInfo() = default;

    virtual status_t writeToParcel(Parcel* parcel) const {
        RETURN_IF_FAILED(parcel->writeString16(mDeviceId));
        RETURN_IF_FAILED(parcel->writeInt32(mPortId));
        RETURN_IF_FAILED(parcel->writeUint32(mType));
        RETURN_IF_FAILED(parcel->writeString16(mAddress));
        RETURN_IF_FAILED(parcel->writeInt32(mDeviceLocation));
        RETURN_IF_FAILED(parcel->writeInt32(mDeviceGroup));
        RETURN_IF_FAILED(parcel->writeInt32(mIndexInTheGroup));
        RETURN_IF_FAILED(writeFloatVector(parcel, mGeometricLocation));
        RETURN_IF_FAILED(writeFloatVector(parcel, mOrientation));
        if (mFrequencyResponses.size() != 2) {
            return BAD_VALUE;
        }
        for (size_t i = 0; i < mFrequencyResponses.size(); i++) {
            RETURN_IF_FAILED(parcel->writeInt32(mFrequencyResponses[i].size()));
            RETURN_IF_FAILED(writeFloatVector(parcel, mFrequencyResponses[i]));
        }
        std::vector<int> channelMapping;
        for (size_t i = 0; i < mChannelMapping.size(); ++i) {
            channelMapping.push_back(mChannelMapping[i]);
        }
        RETURN_IF_FAILED(parcel->writeInt32Vector(channelMapping));
        RETURN_IF_FAILED(parcel->writeFloat(mSensitivity));
        RETURN_IF_FAILED(parcel->writeFloat(mMaxSpl));
        RETURN_IF_FAILED(parcel->writeFloat(mMinSpl));
        RETURN_IF_FAILED(parcel->writeInt32(mDirectionality));
        return OK;
    }

    virtual status_t readFromParcel(const Parcel* parcel) {
        RETURN_IF_FAILED(parcel->readString16(&mDeviceId));
        RETURN_IF_FAILED(parcel->readInt32(&mPortId));
        RETURN_IF_FAILED(parcel->readUint32(&mType));
        RETURN_IF_FAILED(parcel->readString16(&mAddress));
        RETURN_IF_FAILED(parcel->readInt32(&mDeviceLocation));
        RETURN_IF_FAILED(parcel->readInt32(&mDeviceGroup));
        RETURN_IF_FAILED(parcel->readInt32(&mIndexInTheGroup));
        RETURN_IF_FAILED(readFloatVector(parcel, &mGeometricLocation, 3));
        RETURN_IF_FAILED(readFloatVector(parcel, &mOrientation, 3));
        int32_t frequenciesNum;
        RETURN_IF_FAILED(parcel->readInt32(&frequenciesNum));
        Vector<float> frequencies;
        RETURN_IF_FAILED(readFloatVector(parcel, &frequencies, frequenciesNum));
        int32_t responsesNum;
        RETURN_IF_FAILED(parcel->readInt32(&responsesNum));
        Vector<float> responses;
        RETURN_IF_FAILED(readFloatVector(parcel, &responses, responsesNum));
        if (frequencies.size() != responses.size()) {
            return BAD_VALUE;
        }
        mFrequencyResponses.push_back(frequencies);
        mFrequencyResponses.push_back(responses);
        std::vector<int> channelMapping;
        status_t result = parcel->readInt32Vector(&channelMapping);
        if (result != OK) {
            return result;
        }
        if (channelMapping.size() != AUDIO_CHANNEL_COUNT_MAX) {
            return BAD_VALUE;
        }
        for (size_t i = 0; i < channelMapping.size(); i++) {
            mChannelMapping.push_back(channelMapping[i]);
        }
        RETURN_IF_FAILED(parcel->readFloat(&mSensitivity));
        RETURN_IF_FAILED(parcel->readFloat(&mMaxSpl));
        RETURN_IF_FAILED(parcel->readFloat(&mMinSpl));
        RETURN_IF_FAILED(parcel->readInt32(&mDirectionality));
        return OK;
    }

    String16 getDeviceId() const {
        return mDeviceId;
    }

    int getPortId() const {
        return mPortId;
    }

    unsigned int getType() const {
        return mType;
    }

    String16 getAddress() const {
        return mAddress;
    }

    int getDeviceLocation() const {
        return mDeviceLocation;
    }

    int getDeviceGroup() const {
        return mDeviceGroup;
    }

    int getIndexInTheGroup() const {
        return mIndexInTheGroup;
    }

    const Vector<float>& getGeometricLocation() const {
        return mGeometricLocation;
    }

    const Vector<float>& getOrientation() const {
        return mOrientation;
    }

    const Vector<Vector<float>>& getFrequencyResponses() const {
        return mFrequencyResponses;
    }

    const Vector<int>& getChannelMapping() const {
        return mChannelMapping;
    }

    float getSensitivity() const {
        return mSensitivity;
    }

    float getMaxSpl() const {
        return mMaxSpl;
    }

    float getMinSpl() const {
        return mMinSpl;
    }

    int getDirectionality() const {
        return mDirectionality;
    }

private:
    status_t readFloatVector(
            const Parcel* parcel, Vector<float> *vectorPtr, size_t defaultLength) {
        std::unique_ptr<std::vector<float>> v;
        status_t result = parcel->readFloatVector(&v);
        if (result != OK) return result;
        vectorPtr->clear();
        if (v.get() != nullptr) {
            for (const auto& iter : *v) {
                vectorPtr->push_back(iter);
            }
        } else {
            vectorPtr->resize(defaultLength);
        }
        return OK;
    }
    status_t writeFloatVector(Parcel* parcel, const Vector<float>& vector) const {
        std::vector<float> v;
        for (size_t i = 0; i < vector.size(); i++) {
            v.push_back(vector[i]);
        }
        return parcel->writeFloatVector(v);
    }

    String16 mDeviceId;
    int32_t mPortId;
    uint32_t mType;
    String16 mAddress;
    int32_t mDeviceLocation;
    int32_t mDeviceGroup;
    int32_t mIndexInTheGroup;
    Vector<float> mGeometricLocation;
    Vector<float> mOrientation;
    Vector<Vector<float>> mFrequencyResponses;
    Vector<int> mChannelMapping;
    float mSensitivity;
    float mMaxSpl;
    float mMinSpl;
    int32_t mDirectionality;
};

} // namespace media
} // namespace android

#endif
+7 −0
Original line number Diff line number Diff line
@@ -1273,6 +1273,13 @@ float AudioSystem::getStreamVolumeDB(audio_stream_type_t stream, int index, audi
    return aps->getStreamVolumeDB(stream, index, device);
}

status_t AudioSystem::getMicrophones(std::vector<media::MicrophoneInfo> *microphones)
{
    const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
    if (af == 0) return PERMISSION_DENIED;
    return af->getMicrophones(microphones);
}

// ---------------------------------------------------------------------------

int AudioSystem::AudioPolicyServiceClient::addAudioPortCallback(
+23 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@ enum {
    GET_AUDIO_HW_SYNC_FOR_SESSION,
    SYSTEM_READY,
    FRAME_COUNT_HAL,
    LIST_MICROPHONES,
};

#define MAX_ITEMS_PER_LIST 1024
@@ -842,6 +843,18 @@ public:
        }
        return reply.readInt64();
    }
    virtual status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
        status_t status = remote()->transact(LIST_MICROPHONES, data, &reply);
        if (status != NO_ERROR ||
                (status = (status_t)reply.readInt32()) != NO_ERROR) {
            return status;
        }
        status = reply.readParcelableVector(microphones);
        return status;
    }
};

IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
@@ -1407,6 +1420,16 @@ status_t BnAudioFlinger::onTransact(
            reply->writeInt64( frameCountHAL((audio_io_handle_t) data.readInt32()) );
            return NO_ERROR;
        } break;
        case LIST_MICROPHONES: {
            CHECK_INTERFACE(IAudioFlinger, data, reply);
            std::vector<media::MicrophoneInfo> microphones;
            status_t status = getMicrophones(&microphones);
            reply->writeInt32(status);
            if (status == NO_ERROR) {
                reply->writeParcelableVector(microphones);
            }
            return NO_ERROR;
        }
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
+19 −0
Original line number Diff line number Diff line
/*
 * Copyright 2018 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.
 */

package android.media;

parcelable MicrophoneInfo cpp_header "media/MicrophoneInfo.h";
+4 −0
Original line number Diff line number Diff line
@@ -23,11 +23,13 @@
#include <media/AudioIoDescriptor.h>
#include <media/IAudioFlingerClient.h>
#include <media/IAudioPolicyServiceClient.h>
#include <media/MicrophoneInfo.h>
#include <system/audio.h>
#include <system/audio_effect.h>
#include <system/audio_policy.h>
#include <utils/Errors.h>
#include <utils/Mutex.h>
#include <vector>

namespace android {

@@ -336,6 +338,8 @@ public:
    static float    getStreamVolumeDB(
            audio_stream_type_t stream, int index, audio_devices_t device);

    static status_t getMicrophones(std::vector<media::MicrophoneInfo> *microphones);

    // ----------------------------------------------------------------------------

    class AudioPortCallback : public RefBase
Loading