110548295023bee99108e418499aff09fe578211eMikhail Naganov/*
210548295023bee99108e418499aff09fe578211eMikhail Naganov * Copyright (C) 2016 The Android Open Source Project
310548295023bee99108e418499aff09fe578211eMikhail Naganov *
410548295023bee99108e418499aff09fe578211eMikhail Naganov * Licensed under the Apache License, Version 2.0 (the "License");
510548295023bee99108e418499aff09fe578211eMikhail Naganov * you may not use this file except in compliance with the License.
610548295023bee99108e418499aff09fe578211eMikhail Naganov * You may obtain a copy of the License at
710548295023bee99108e418499aff09fe578211eMikhail Naganov *
810548295023bee99108e418499aff09fe578211eMikhail Naganov *      http://www.apache.org/licenses/LICENSE-2.0
910548295023bee99108e418499aff09fe578211eMikhail Naganov *
1010548295023bee99108e418499aff09fe578211eMikhail Naganov * Unless required by applicable law or agreed to in writing, software
1110548295023bee99108e418499aff09fe578211eMikhail Naganov * distributed under the License is distributed on an "AS IS" BASIS,
1210548295023bee99108e418499aff09fe578211eMikhail Naganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1310548295023bee99108e418499aff09fe578211eMikhail Naganov * See the License for the specific language governing permissions and
1410548295023bee99108e418499aff09fe578211eMikhail Naganov * limitations under the License.
1510548295023bee99108e418499aff09fe578211eMikhail Naganov */
1610548295023bee99108e418499aff09fe578211eMikhail Naganov
17d6e4f03acf5fa1e76b75e33af7a26f248a92be9aSteven Moreland#ifndef ANDROID_HARDWARE_AUDIO_V2_0_STREAM_H
18d6e4f03acf5fa1e76b75e33af7a26f248a92be9aSteven Moreland#define ANDROID_HARDWARE_AUDIO_V2_0_STREAM_H
1910548295023bee99108e418499aff09fe578211eMikhail Naganov
20f74df70fd777cc2fa426e992c64c1f4aa78a9122Mikhail Naganov#include <vector>
21f74df70fd777cc2fa426e992c64c1f4aa78a9122Mikhail Naganov
2210548295023bee99108e418499aff09fe578211eMikhail Naganov#include <android/hardware/audio/2.0/IStream.h>
237deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent#include <hardware/audio.h>
2410548295023bee99108e418499aff09fe578211eMikhail Naganov#include <hidl/Status.h>
2510548295023bee99108e418499aff09fe578211eMikhail Naganov
2610548295023bee99108e418499aff09fe578211eMikhail Naganov#include <hidl/MQDescriptor.h>
2710548295023bee99108e418499aff09fe578211eMikhail Naganov
2810548295023bee99108e418499aff09fe578211eMikhail Naganov#include "ParametersUtil.h"
2910548295023bee99108e418499aff09fe578211eMikhail Naganov
3010548295023bee99108e418499aff09fe578211eMikhail Naganovnamespace android {
3110548295023bee99108e418499aff09fe578211eMikhail Naganovnamespace hardware {
3210548295023bee99108e418499aff09fe578211eMikhail Naganovnamespace audio {
3310548295023bee99108e418499aff09fe578211eMikhail Naganovnamespace V2_0 {
3410548295023bee99108e418499aff09fe578211eMikhail Naganovnamespace implementation {
3510548295023bee99108e418499aff09fe578211eMikhail Naganov
3610548295023bee99108e418499aff09fe578211eMikhail Naganovusing ::android::hardware::audio::common::V2_0::AudioChannelMask;
3710548295023bee99108e418499aff09fe578211eMikhail Naganovusing ::android::hardware::audio::common::V2_0::AudioDevice;
3810548295023bee99108e418499aff09fe578211eMikhail Naganovusing ::android::hardware::audio::common::V2_0::AudioFormat;
3910548295023bee99108e418499aff09fe578211eMikhail Naganovusing ::android::hardware::audio::V2_0::DeviceAddress;
4010548295023bee99108e418499aff09fe578211eMikhail Naganovusing ::android::hardware::audio::V2_0::IStream;
4110548295023bee99108e418499aff09fe578211eMikhail Naganovusing ::android::hardware::audio::V2_0::ParameterValue;
4210548295023bee99108e418499aff09fe578211eMikhail Naganovusing ::android::hardware::audio::V2_0::Result;
4310548295023bee99108e418499aff09fe578211eMikhail Naganovusing ::android::hardware::Return;
4410548295023bee99108e418499aff09fe578211eMikhail Naganovusing ::android::hardware::Void;
4510548295023bee99108e418499aff09fe578211eMikhail Naganovusing ::android::hardware::hidl_vec;
4610548295023bee99108e418499aff09fe578211eMikhail Naganovusing ::android::hardware::hidl_string;
4710548295023bee99108e418499aff09fe578211eMikhail Naganovusing ::android::sp;
4810548295023bee99108e418499aff09fe578211eMikhail Naganov
4910548295023bee99108e418499aff09fe578211eMikhail Naganovstruct Stream : public IStream, public ParametersUtil {
5010548295023bee99108e418499aff09fe578211eMikhail Naganov    explicit Stream(audio_stream_t* stream);
5110548295023bee99108e418499aff09fe578211eMikhail Naganov
5210548295023bee99108e418499aff09fe578211eMikhail Naganov    // Methods from ::android::hardware::audio::V2_0::IStream follow.
5310548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<uint64_t> getFrameSize()  override;
5410548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<uint64_t> getFrameCount()  override;
5510548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<uint64_t> getBufferSize()  override;
5610548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<uint32_t> getSampleRate()  override;
5710548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<void> getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb)  override;
5810548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<Result> setSampleRate(uint32_t sampleRateHz)  override;
5910548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<AudioChannelMask> getChannelMask()  override;
6010548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<void> getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb)  override;
6110548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<Result> setChannelMask(AudioChannelMask mask)  override;
6210548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<AudioFormat> getFormat()  override;
6310548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<void> getSupportedFormats(getSupportedFormats_cb _hidl_cb)  override;
6410548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<Result> setFormat(AudioFormat format)  override;
6510548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<void> getAudioProperties(getAudioProperties_cb _hidl_cb)  override;
6610548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<Result> addEffect(uint64_t effectId)  override;
6710548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<Result> removeEffect(uint64_t effectId)  override;
6810548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<Result> standby()  override;
6910548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<AudioDevice> getDevice()  override;
7010548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<Result> setDevice(const DeviceAddress& address)  override;
7110548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<Result> setConnectedState(const DeviceAddress& address, bool connected)  override;
7210548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<Result> setHwAvSync(uint32_t hwAvSync)  override;
7310548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<void> getParameters(
7410548295023bee99108e418499aff09fe578211eMikhail Naganov            const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb)  override;
7510548295023bee99108e418499aff09fe578211eMikhail Naganov    Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters)  override;
7670b9a15df00a42b319279d903bf5923564920e3bMartijn Coenen    Return<void> debugDump(const hidl_handle& fd)  override;
777deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    Return<Result> start() override;
787deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    Return<Result> stop() override;
797deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    Return<void> createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override;
807deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    Return<void> getMmapPosition(getMmapPosition_cb _hidl_cb) override;
81b29438ef70549a331d11c0384c53cf1dc6e7f0beMikhail Naganov    Return<Result> close()  override;
8210548295023bee99108e418499aff09fe578211eMikhail Naganov
8310548295023bee99108e418499aff09fe578211eMikhail Naganov    // Utility methods for extending interfaces.
84f74df70fd777cc2fa426e992c64c1f4aa78a9122Mikhail Naganov    static Result analyzeStatus(const char* funcName, int status);
85f74df70fd777cc2fa426e992c64c1f4aa78a9122Mikhail Naganov    static Result analyzeStatus(const char* funcName, int status,
86f74df70fd777cc2fa426e992c64c1f4aa78a9122Mikhail Naganov                                const std::vector<int>& ignoreErrors);
8710548295023bee99108e418499aff09fe578211eMikhail Naganov
88f74df70fd777cc2fa426e992c64c1f4aa78a9122Mikhail Naganov   private:
8910548295023bee99108e418499aff09fe578211eMikhail Naganov    audio_stream_t *mStream;
9010548295023bee99108e418499aff09fe578211eMikhail Naganov
9110548295023bee99108e418499aff09fe578211eMikhail Naganov    virtual ~Stream();
9210548295023bee99108e418499aff09fe578211eMikhail Naganov
9310548295023bee99108e418499aff09fe578211eMikhail Naganov    // Methods from ParametersUtil.
9410548295023bee99108e418499aff09fe578211eMikhail Naganov    char* halGetParameters(const char* keys) override;
9510548295023bee99108e418499aff09fe578211eMikhail Naganov    int halSetParameters(const char* keysAndValues) override;
9610548295023bee99108e418499aff09fe578211eMikhail Naganov};
9710548295023bee99108e418499aff09fe578211eMikhail Naganov
987deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent
997deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurenttemplate <typename T>
1007deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurentstruct StreamMmap : public RefBase {
1017deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    explicit StreamMmap(T* stream) : mStream(stream) {}
1027deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent
1037deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    Return<Result> start();
1047deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    Return<Result> stop();
1057deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    Return<void> createMmapBuffer(
1067deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent            int32_t minSizeFrames, size_t frameSize, IStream::createMmapBuffer_cb _hidl_cb);
1077deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    Return<void> getMmapPosition(IStream::getMmapPosition_cb _hidl_cb);
1087deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent
1097deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent private:
1107deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent   StreamMmap() {}
1117deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent
1127deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent   T *mStream;
1137deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent};
1147deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent
1157deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurenttemplate <typename T>
1167deb7dad39e58b6e5de812075950adc27cd51d95Eric LaurentReturn<Result> StreamMmap<T>::start() {
1177deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    if (mStream->start == NULL) return Result::NOT_SUPPORTED;
1187deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    int result = mStream->start(mStream);
1197deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    return Stream::analyzeStatus("start", result);
1207deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent}
1217deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent
1227deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurenttemplate <typename T>
1237deb7dad39e58b6e5de812075950adc27cd51d95Eric LaurentReturn<Result> StreamMmap<T>::stop() {
1247deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    if (mStream->stop == NULL) return Result::NOT_SUPPORTED;
1257deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    int result = mStream->stop(mStream);
1267deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    return Stream::analyzeStatus("stop", result);
1277deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent}
1287deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent
1297deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurenttemplate <typename T>
1307deb7dad39e58b6e5de812075950adc27cd51d95Eric LaurentReturn<void> StreamMmap<T>::createMmapBuffer(int32_t minSizeFrames, size_t frameSize,
1317deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent                                             IStream::createMmapBuffer_cb _hidl_cb) {
1327deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    Result retval(Result::NOT_SUPPORTED);
1337deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    MmapBufferInfo info;
13445d4d3025dfbdba78d2490044b63fc8ee804269bMartijn Coenen    native_handle_t* hidlHandle = nullptr;
1357deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent
1367deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    if (mStream->create_mmap_buffer != NULL) {
1377deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent        struct audio_mmap_buffer_info halInfo;
1387deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent        retval = Stream::analyzeStatus(
1397deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent                "create_mmap_buffer",
1407deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent                mStream->create_mmap_buffer(mStream, minSizeFrames, &halInfo));
1417deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent        if (retval == Result::OK) {
14245d4d3025dfbdba78d2490044b63fc8ee804269bMartijn Coenen            hidlHandle = native_handle_create(1, 0);
1437deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent            hidlHandle->data[0] = halInfo.shared_memory_fd;
1447deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent            info.sharedMemory = hidl_memory("audio_buffer", hidlHandle,
1457deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent                                            frameSize *halInfo.buffer_size_frames);
1467deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent            info.bufferSizeFrames = halInfo.buffer_size_frames;
1477deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent            info.burstSizeFrames = halInfo.burst_size_frames;
1487deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent        }
1497deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    }
1507deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    _hidl_cb(retval, info);
15145d4d3025dfbdba78d2490044b63fc8ee804269bMartijn Coenen    if (hidlHandle != nullptr) {
15245d4d3025dfbdba78d2490044b63fc8ee804269bMartijn Coenen        native_handle_delete(hidlHandle);
15345d4d3025dfbdba78d2490044b63fc8ee804269bMartijn Coenen    }
1547deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    return Void();
1557deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent}
1567deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent
1577deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurenttemplate <typename T>
1587deb7dad39e58b6e5de812075950adc27cd51d95Eric LaurentReturn<void> StreamMmap<T>::getMmapPosition(IStream::getMmapPosition_cb _hidl_cb) {
1597deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    Result retval(Result::NOT_SUPPORTED);
1607deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    MmapPosition position;
1617deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent
1627deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    if (mStream->get_mmap_position != NULL) {
1637deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent        struct audio_mmap_position halPosition;
1647deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent        retval = Stream::analyzeStatus(
1657deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent                "get_mmap_position",
1667deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent                mStream->get_mmap_position(mStream, &halPosition));
1677deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent        if (retval == Result::OK) {
1687deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent            position.timeNanoseconds = halPosition.time_nanoseconds;
1697deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent            position.positionFrames = halPosition.position_frames;
1707deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent        }
1717deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    }
1727deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    _hidl_cb(retval, position);
1737deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent    return Void();
1747deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent}
1757deb7dad39e58b6e5de812075950adc27cd51d95Eric Laurent
17610548295023bee99108e418499aff09fe578211eMikhail Naganov}  // namespace implementation
17710548295023bee99108e418499aff09fe578211eMikhail Naganov}  // namespace V2_0
17810548295023bee99108e418499aff09fe578211eMikhail Naganov}  // namespace audio
17910548295023bee99108e418499aff09fe578211eMikhail Naganov}  // namespace hardware
18010548295023bee99108e418499aff09fe578211eMikhail Naganov}  // namespace android
18110548295023bee99108e418499aff09fe578211eMikhail Naganov
182d6e4f03acf5fa1e76b75e33af7a26f248a92be9aSteven Moreland#endif  // ANDROID_HARDWARE_AUDIO_V2_0_STREAM_H
183