1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_HARDWARE_AUDIO_V2_0_STREAM_H 18 #define ANDROID_HARDWARE_AUDIO_V2_0_STREAM_H 19 20 #include <vector> 21 22 #include <android/hardware/audio/2.0/IStream.h> 23 #include <hardware/audio.h> 24 #include <hidl/Status.h> 25 26 #include <hidl/MQDescriptor.h> 27 28 #include "ParametersUtil.h" 29 30 namespace android { 31 namespace hardware { 32 namespace audio { 33 namespace V2_0 { 34 namespace implementation { 35 36 using ::android::hardware::audio::common::V2_0::AudioChannelMask; 37 using ::android::hardware::audio::common::V2_0::AudioDevice; 38 using ::android::hardware::audio::common::V2_0::AudioFormat; 39 using ::android::hardware::audio::V2_0::DeviceAddress; 40 using ::android::hardware::audio::V2_0::IStream; 41 using ::android::hardware::audio::V2_0::ParameterValue; 42 using ::android::hardware::audio::V2_0::Result; 43 using ::android::hardware::Return; 44 using ::android::hardware::Void; 45 using ::android::hardware::hidl_vec; 46 using ::android::hardware::hidl_string; 47 using ::android::sp; 48 49 struct Stream : public IStream, public ParametersUtil { 50 explicit Stream(audio_stream_t* stream); 51 52 /** 1GiB is the maximum buffer size the HAL client is allowed to request. 53 * This value has been chosen to be under SIZE_MAX and still big enough 54 * for all audio use case. 55 * Keep private for 2.0, put in .hal in 2.1 56 */ 57 static constexpr uint32_t MAX_BUFFER_SIZE = 2 << 30 /* == 1GiB */; 58 59 // Methods from ::android::hardware::audio::V2_0::IStream follow. 60 Return<uint64_t> getFrameSize() override; 61 Return<uint64_t> getFrameCount() override; 62 Return<uint64_t> getBufferSize() override; 63 Return<uint32_t> getSampleRate() override; 64 Return<void> getSupportedSampleRates(getSupportedSampleRates_cb _hidl_cb) override; 65 Return<Result> setSampleRate(uint32_t sampleRateHz) override; 66 Return<AudioChannelMask> getChannelMask() override; 67 Return<void> getSupportedChannelMasks(getSupportedChannelMasks_cb _hidl_cb) override; 68 Return<Result> setChannelMask(AudioChannelMask mask) override; 69 Return<AudioFormat> getFormat() override; 70 Return<void> getSupportedFormats(getSupportedFormats_cb _hidl_cb) override; 71 Return<Result> setFormat(AudioFormat format) override; 72 Return<void> getAudioProperties(getAudioProperties_cb _hidl_cb) override; 73 Return<Result> addEffect(uint64_t effectId) override; 74 Return<Result> removeEffect(uint64_t effectId) override; 75 Return<Result> standby() override; 76 Return<AudioDevice> getDevice() override; 77 Return<Result> setDevice(const DeviceAddress& address) override; 78 Return<Result> setConnectedState(const DeviceAddress& address, bool connected) override; 79 Return<Result> setHwAvSync(uint32_t hwAvSync) override; 80 Return<void> getParameters( 81 const hidl_vec<hidl_string>& keys, getParameters_cb _hidl_cb) override; 82 Return<Result> setParameters(const hidl_vec<ParameterValue>& parameters) override; 83 Return<void> debugDump(const hidl_handle& fd) override; 84 Return<Result> start() override; 85 Return<Result> stop() override; 86 Return<void> createMmapBuffer(int32_t minSizeFrames, createMmapBuffer_cb _hidl_cb) override; 87 Return<void> getMmapPosition(getMmapPosition_cb _hidl_cb) override; 88 Return<Result> close() override; 89 90 // Utility methods for extending interfaces. 91 static Result analyzeStatus(const char* funcName, int status); 92 static Result analyzeStatus(const char* funcName, int status, 93 const std::vector<int>& ignoreErrors); 94 95 private: 96 audio_stream_t *mStream; 97 98 virtual ~Stream(); 99 100 // Methods from ParametersUtil. 101 char* halGetParameters(const char* keys) override; 102 int halSetParameters(const char* keysAndValues) override; 103 }; 104 105 106 template <typename T> 107 struct StreamMmap : public RefBase { 108 explicit StreamMmap(T* stream) : mStream(stream) {} 109 110 Return<Result> start(); 111 Return<Result> stop(); 112 Return<void> createMmapBuffer( 113 int32_t minSizeFrames, size_t frameSize, IStream::createMmapBuffer_cb _hidl_cb); 114 Return<void> getMmapPosition(IStream::getMmapPosition_cb _hidl_cb); 115 116 private: 117 StreamMmap() {} 118 119 T *mStream; 120 }; 121 122 template <typename T> 123 Return<Result> StreamMmap<T>::start() { 124 if (mStream->start == NULL) return Result::NOT_SUPPORTED; 125 int result = mStream->start(mStream); 126 return Stream::analyzeStatus("start", result); 127 } 128 129 template <typename T> 130 Return<Result> StreamMmap<T>::stop() { 131 if (mStream->stop == NULL) return Result::NOT_SUPPORTED; 132 int result = mStream->stop(mStream); 133 return Stream::analyzeStatus("stop", result); 134 } 135 136 template <typename T> 137 Return<void> StreamMmap<T>::createMmapBuffer(int32_t minSizeFrames, size_t frameSize, 138 IStream::createMmapBuffer_cb _hidl_cb) { 139 Result retval(Result::NOT_SUPPORTED); 140 MmapBufferInfo info; 141 native_handle_t* hidlHandle = nullptr; 142 143 if (mStream->create_mmap_buffer != NULL) { 144 struct audio_mmap_buffer_info halInfo; 145 retval = Stream::analyzeStatus( 146 "create_mmap_buffer", 147 mStream->create_mmap_buffer(mStream, minSizeFrames, &halInfo)); 148 if (retval == Result::OK) { 149 hidlHandle = native_handle_create(1, 0); 150 hidlHandle->data[0] = halInfo.shared_memory_fd; 151 info.sharedMemory = hidl_memory("audio_buffer", hidlHandle, 152 frameSize *halInfo.buffer_size_frames); 153 info.bufferSizeFrames = halInfo.buffer_size_frames; 154 info.burstSizeFrames = halInfo.burst_size_frames; 155 } 156 } 157 _hidl_cb(retval, info); 158 if (hidlHandle != nullptr) { 159 native_handle_delete(hidlHandle); 160 } 161 return Void(); 162 } 163 164 template <typename T> 165 Return<void> StreamMmap<T>::getMmapPosition(IStream::getMmapPosition_cb _hidl_cb) { 166 Result retval(Result::NOT_SUPPORTED); 167 MmapPosition position; 168 169 if (mStream->get_mmap_position != NULL) { 170 struct audio_mmap_position halPosition; 171 retval = Stream::analyzeStatus( 172 "get_mmap_position", 173 mStream->get_mmap_position(mStream, &halPosition)); 174 if (retval == Result::OK) { 175 position.timeNanoseconds = halPosition.time_nanoseconds; 176 position.positionFrames = halPosition.position_frames; 177 } 178 } 179 _hidl_cb(retval, position); 180 return Void(); 181 } 182 183 } // namespace implementation 184 } // namespace V2_0 185 } // namespace audio 186 } // namespace hardware 187 } // namespace android 188 189 #endif // ANDROID_HARDWARE_AUDIO_V2_0_STREAM_H 190