11dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov/* 21dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov * Copyright (C) 2016 The Android Open Source Project 31dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov * 41dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov * Licensed under the Apache License, Version 2.0 (the "License"); 51dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov * you may not use this file except in compliance with the License. 61dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov * You may obtain a copy of the License at 71dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov * 81dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov * http://www.apache.org/licenses/LICENSE-2.0 91dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov * 101dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov * Unless required by applicable law or agreed to in writing, software 111dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov * distributed under the License is distributed on an "AS IS" BASIS, 121dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov * See the License for the specific language governing permissions and 141dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov * limitations under the License. 151dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov */ 161dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 17a0c91339814f37ea78365afb436c9f3d1f0a0090Mikhail Naganov#define LOG_TAG "StreamHalLocal" 181dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov//#define LOG_NDEBUG 0 191dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 20cbc8f617c1aebef5d041fa40dcd38a5466690b99Mikhail Naganov#include <hardware/audio.h> 211dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov#include <utils/Log.h> 221dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 231dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov#include "DeviceHalLocal.h" 241dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov#include "StreamHalLocal.h" 251dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 261dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovnamespace android { 271dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 281dc98674f701dada94143b4d31b7221c58346c6cMikhail NaganovStreamHalLocal::StreamHalLocal(audio_stream_t *stream, sp<DeviceHalLocal> device) 29953608fabc2b1253850f9922b15fd1392bde784cAndy Hung : mDevice(device), 30953608fabc2b1253850f9922b15fd1392bde784cAndy Hung mStream(stream) { 31953608fabc2b1253850f9922b15fd1392bde784cAndy Hung // Instrument audio signal power logging. 32953608fabc2b1253850f9922b15fd1392bde784cAndy Hung // Note: This assumes channel mask, format, and sample rate do not change after creation. 33953608fabc2b1253850f9922b15fd1392bde784cAndy Hung if (mStream != nullptr && mStreamPowerLog.isUserDebugOrEngBuild()) { 34953608fabc2b1253850f9922b15fd1392bde784cAndy Hung mStreamPowerLog.init(mStream->get_sample_rate(mStream), 35953608fabc2b1253850f9922b15fd1392bde784cAndy Hung mStream->get_channels(mStream), 36953608fabc2b1253850f9922b15fd1392bde784cAndy Hung mStream->get_format(mStream)); 37953608fabc2b1253850f9922b15fd1392bde784cAndy Hung } 381dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 391dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 401dc98674f701dada94143b4d31b7221c58346c6cMikhail NaganovStreamHalLocal::~StreamHalLocal() { 411dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov mStream = 0; 421dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov mDevice.clear(); 431dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 441dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 451dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamHalLocal::getSampleRate(uint32_t *rate) { 461dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *rate = mStream->get_sample_rate(mStream); 471dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return OK; 481dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 491dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 501dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamHalLocal::getBufferSize(size_t *size) { 511dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *size = mStream->get_buffer_size(mStream); 521dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return OK; 531dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 541dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 551dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamHalLocal::getChannelMask(audio_channel_mask_t *mask) { 561dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *mask = mStream->get_channels(mStream); 571dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return OK; 581dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 591dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 601dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamHalLocal::getFormat(audio_format_t *format) { 611dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *format = mStream->get_format(mStream); 621dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return OK; 631dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 641dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 651dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamHalLocal::getAudioProperties( 661dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov uint32_t *sampleRate, audio_channel_mask_t *mask, audio_format_t *format) { 671dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *sampleRate = mStream->get_sample_rate(mStream); 681dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *mask = mStream->get_channels(mStream); 691dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *format = mStream->get_format(mStream); 701dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return OK; 711dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 721dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 731dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamHalLocal::setParameters(const String8& kvPairs) { 741dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return mStream->set_parameters(mStream, kvPairs.string()); 751dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 761dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 771dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamHalLocal::getParameters(const String8& keys, String8 *values) { 781dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov char *halValues = mStream->get_parameters(mStream, keys.string()); 791dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (halValues != NULL) { 801dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov values->setTo(halValues); 811dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov free(halValues); 821dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } else { 831dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov values->clear(); 841dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } 851dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return OK; 861dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 871dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 889e79c70529c07f2157f8077f024f42fa5c9e22f9Dan Willemsenstatus_t StreamHalLocal::addEffect(sp<EffectHalInterface>) { 899e79c70529c07f2157f8077f024f42fa5c9e22f9Dan Willemsen LOG_ALWAYS_FATAL("Local streams can not have effects"); 909e79c70529c07f2157f8077f024f42fa5c9e22f9Dan Willemsen return INVALID_OPERATION; 911dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 921dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 939e79c70529c07f2157f8077f024f42fa5c9e22f9Dan Willemsenstatus_t StreamHalLocal::removeEffect(sp<EffectHalInterface>) { 949e79c70529c07f2157f8077f024f42fa5c9e22f9Dan Willemsen LOG_ALWAYS_FATAL("Local streams can not have effects"); 959e79c70529c07f2157f8077f024f42fa5c9e22f9Dan Willemsen return INVALID_OPERATION; 961dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 971dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 981dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamHalLocal::standby() { 991dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return mStream->standby(mStream); 1001dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 1011dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 1021dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamHalLocal::dump(int fd) { 103953608fabc2b1253850f9922b15fd1392bde784cAndy Hung status_t status = mStream->dump(mStream, fd); 104953608fabc2b1253850f9922b15fd1392bde784cAndy Hung mStreamPowerLog.dump(fd); 105953608fabc2b1253850f9922b15fd1392bde784cAndy Hung return status; 1061dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 1071dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 108e1c4b5d7a94c21b8ce0c5707b4af84de596fbb79Mikhail Naganovstatus_t StreamHalLocal::setHalThreadPriority(int) { 109e1c4b5d7a94c21b8ce0c5707b4af84de596fbb79Mikhail Naganov // Don't need to do anything as local hal is executed by audioflinger directly 110e1c4b5d7a94c21b8ce0c5707b4af84de596fbb79Mikhail Naganov // on the same thread. 111e1c4b5d7a94c21b8ce0c5707b4af84de596fbb79Mikhail Naganov return OK; 112e1c4b5d7a94c21b8ce0c5707b4af84de596fbb79Mikhail Naganov} 113e1c4b5d7a94c21b8ce0c5707b4af84de596fbb79Mikhail Naganov 1141dc98674f701dada94143b4d31b7221c58346c6cMikhail NaganovStreamOutHalLocal::StreamOutHalLocal(audio_stream_out_t *stream, sp<DeviceHalLocal> device) 1151dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov : StreamHalLocal(&stream->common, device), mStream(stream) { 1161dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 1171dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 1181dc98674f701dada94143b4d31b7221c58346c6cMikhail NaganovStreamOutHalLocal::~StreamOutHalLocal() { 1191dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov mCallback.clear(); 1201dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov mDevice->closeOutputStream(mStream); 1211dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov mStream = 0; 1221dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 1231dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 1241dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamOutHalLocal::getFrameSize(size_t *size) { 1251dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *size = audio_stream_out_frame_size(mStream); 1261dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return OK; 1271dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 1281dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 1291dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamOutHalLocal::getLatency(uint32_t *latency) { 1301dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *latency = mStream->get_latency(mStream); 1311dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return OK; 1321dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 1331dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 1341dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamOutHalLocal::setVolume(float left, float right) { 1351dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mStream->set_volume == NULL) return INVALID_OPERATION; 1361dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return mStream->set_volume(mStream, left, right); 1371dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 1381dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 1391dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamOutHalLocal::write(const void *buffer, size_t bytes, size_t *written) { 1401dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ssize_t writeResult = mStream->write(mStream, buffer, bytes); 1411dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (writeResult > 0) { 1421dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *written = writeResult; 143953608fabc2b1253850f9922b15fd1392bde784cAndy Hung mStreamPowerLog.log(buffer, *written); 1441dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return OK; 1451dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } else { 1461dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *written = 0; 1471dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return writeResult; 1481dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } 1491dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 1501dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 1511dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamOutHalLocal::getRenderPosition(uint32_t *dspFrames) { 1521dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return mStream->get_render_position(mStream, dspFrames); 1531dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 1541dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 1551dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamOutHalLocal::getNextWriteTimestamp(int64_t *timestamp) { 1561dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mStream->get_next_write_timestamp == NULL) return INVALID_OPERATION; 1571dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return mStream->get_next_write_timestamp(mStream, timestamp); 1581dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 1591dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 16015897e459c5086058e73b3e91690320a7bb46d4aMikhail Naganovstatus_t StreamOutHalLocal::setCallback(wp<StreamOutHalInterfaceCallback> callback) { 1611dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mStream->set_callback == NULL) return INVALID_OPERATION; 1621dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov status_t result = mStream->set_callback(mStream, StreamOutHalLocal::asyncCallback, this); 1631dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (result == OK) { 1641dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov mCallback = callback; 1651dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } 1661dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return result; 1671dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 1681dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 1691dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov// static 1701dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovint StreamOutHalLocal::asyncCallback(stream_callback_event_t event, void*, void *cookie) { 1711dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov // We act as if we gave a wp<StreamOutHalLocal> to HAL. This way we should handle 1721dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov // correctly the case when the callback is invoked while StreamOutHalLocal's destructor is 1731dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov // already running, because the destructor is invoked after the refcount has been atomically 1741dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov // decremented. 1756b111f32247800dccd34dd396e731b9e7888b185Mikhail Naganov wp<StreamOutHalLocal> weakSelf(static_cast<StreamOutHalLocal*>(cookie)); 1761dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov sp<StreamOutHalLocal> self = weakSelf.promote(); 1771dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (self == 0) return 0; 1781dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov sp<StreamOutHalInterfaceCallback> callback = self->mCallback.promote(); 1791dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (callback == 0) return 0; 1801dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGV("asyncCallback() event %d", event); 1811dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov switch (event) { 1821dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov case STREAM_CBK_EVENT_WRITE_READY: 1831dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov callback->onWriteReady(); 1841dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov break; 1851dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov case STREAM_CBK_EVENT_DRAIN_READY: 1861dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov callback->onDrainReady(); 1871dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov break; 1881dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov case STREAM_CBK_EVENT_ERROR: 1891dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov callback->onError(); 1901dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov break; 1911dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov default: 1921dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ALOGW("asyncCallback() unknown event %d", event); 1931dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov break; 1941dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } 1951dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return 0; 1961dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 1971dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 1981dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamOutHalLocal::supportsPauseAndResume(bool *supportsPause, bool *supportsResume) { 1991dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *supportsPause = mStream->pause != NULL; 2001dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *supportsResume = mStream->resume != NULL; 2011dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return OK; 2021dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 2031dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 2041dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamOutHalLocal::pause() { 2051dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mStream->pause == NULL) return INVALID_OPERATION; 2061dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return mStream->pause(mStream); 2071dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 2081dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 2091dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamOutHalLocal::resume() { 2101dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mStream->resume == NULL) return INVALID_OPERATION; 2111dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return mStream->resume(mStream); 2121dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 2131dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 2141dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamOutHalLocal::supportsDrain(bool *supportsDrain) { 2151dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *supportsDrain = mStream->drain != NULL; 2161dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return OK; 2171dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 2181dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 219cbc8f617c1aebef5d041fa40dcd38a5466690b99Mikhail Naganovstatus_t StreamOutHalLocal::drain(bool earlyNotify) { 2201dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mStream->drain == NULL) return INVALID_OPERATION; 221cbc8f617c1aebef5d041fa40dcd38a5466690b99Mikhail Naganov return mStream->drain(mStream, earlyNotify ? AUDIO_DRAIN_EARLY_NOTIFY : AUDIO_DRAIN_ALL); 2221dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 2231dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 2241dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamOutHalLocal::flush() { 2251dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mStream->flush == NULL) return INVALID_OPERATION; 2261dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return mStream->flush(mStream); 2271dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 2281dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 2291dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamOutHalLocal::getPresentationPosition(uint64_t *frames, struct timespec *timestamp) { 2301dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mStream->get_presentation_position == NULL) return INVALID_OPERATION; 2311dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return mStream->get_presentation_position(mStream, frames, timestamp); 2321dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 2331dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 234a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocardstatus_t StreamOutHalLocal::updateSourceMetadata(const SourceMetadata& sourceMetadata) { 235a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard if (mStream->update_source_metadata == nullptr) { 236a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard return INVALID_OPERATION; 237a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard } 238a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard const source_metadata_t metadata { 239a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard .track_count = sourceMetadata.tracks.size(), 240a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard // const cast is fine as it is in a const structure 241a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard .tracks = const_cast<playback_track_metadata*>(sourceMetadata.tracks.data()), 242a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard }; 243a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard mStream->update_source_metadata(mStream, &metadata); 244a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard return OK; 245a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard} 246a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard 247af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurentstatus_t StreamOutHalLocal::start() { 248af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent if (mStream->start == NULL) return INVALID_OPERATION; 249af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent return mStream->start(mStream); 250af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent} 251af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent 252af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurentstatus_t StreamOutHalLocal::stop() { 253af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent if (mStream->stop == NULL) return INVALID_OPERATION; 254af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent return mStream->stop(mStream); 255af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent} 256af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent 257af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurentstatus_t StreamOutHalLocal::createMmapBuffer(int32_t minSizeFrames, 258af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent struct audio_mmap_buffer_info *info) { 259af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent if (mStream->create_mmap_buffer == NULL) return INVALID_OPERATION; 260af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent return mStream->create_mmap_buffer(mStream, minSizeFrames, info); 261af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent} 262af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent 263af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurentstatus_t StreamOutHalLocal::getMmapPosition(struct audio_mmap_position *position) { 264af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent if (mStream->get_mmap_position == NULL) return INVALID_OPERATION; 265af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent return mStream->get_mmap_position(mStream, position); 266af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent} 2671dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 2681dc98674f701dada94143b4d31b7221c58346c6cMikhail NaganovStreamInHalLocal::StreamInHalLocal(audio_stream_in_t *stream, sp<DeviceHalLocal> device) 2691dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov : StreamHalLocal(&stream->common, device), mStream(stream) { 2701dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 2711dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 2721dc98674f701dada94143b4d31b7221c58346c6cMikhail NaganovStreamInHalLocal::~StreamInHalLocal() { 2731dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov mDevice->closeInputStream(mStream); 2741dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov mStream = 0; 2751dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 2761dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 2771dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamInHalLocal::getFrameSize(size_t *size) { 2781dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *size = audio_stream_in_frame_size(mStream); 2791dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return OK; 2801dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 2811dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 2821dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamInHalLocal::setGain(float gain) { 2831dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return mStream->set_gain(mStream, gain); 2841dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 2851dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 2861dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamInHalLocal::read(void *buffer, size_t bytes, size_t *read) { 2871dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov ssize_t readResult = mStream->read(mStream, buffer, bytes); 2881dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (readResult > 0) { 2891dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *read = readResult; 290953608fabc2b1253850f9922b15fd1392bde784cAndy Hung mStreamPowerLog.log( buffer, *read); 2911dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return OK; 2921dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } else { 2931dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *read = 0; 2941dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return readResult; 2951dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov } 2961dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 2971dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 2981dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamInHalLocal::getInputFramesLost(uint32_t *framesLost) { 2991dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov *framesLost = mStream->get_input_frames_lost(mStream); 3001dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return OK; 3011dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 3021dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 3031dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganovstatus_t StreamInHalLocal::getCapturePosition(int64_t *frames, int64_t *time) { 3041dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov if (mStream->get_capture_position == NULL) return INVALID_OPERATION; 3051dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov return mStream->get_capture_position(mStream, frames, time); 3061dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} 3071dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov 308a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocardstatus_t StreamInHalLocal::updateSinkMetadata(const SinkMetadata& sinkMetadata) { 309a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard if (mStream->update_sink_metadata == nullptr) { 310a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard return INVALID_OPERATION; 311a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard } 312a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard const sink_metadata_t metadata { 313a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard .track_count = sinkMetadata.tracks.size(), 314a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard // const cast is fine as it is in a const structure 315a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard .tracks = const_cast<record_track_metadata*>(sinkMetadata.tracks.data()), 316a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard }; 317a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard mStream->update_sink_metadata(mStream, &metadata); 318a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard return OK; 319a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard} 320a8975a7e857fd745fc88d226d86b53ae088eafb9Kevin Rocard 321af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurentstatus_t StreamInHalLocal::start() { 322af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent if (mStream->start == NULL) return INVALID_OPERATION; 323af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent return mStream->start(mStream); 324af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent} 325af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent 326af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurentstatus_t StreamInHalLocal::stop() { 327af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent if (mStream->stop == NULL) return INVALID_OPERATION; 328af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent return mStream->stop(mStream); 329af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent} 330af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent 331af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurentstatus_t StreamInHalLocal::createMmapBuffer(int32_t minSizeFrames, 332af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent struct audio_mmap_buffer_info *info) { 333af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent if (mStream->create_mmap_buffer == NULL) return INVALID_OPERATION; 334af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent return mStream->create_mmap_buffer(mStream, minSizeFrames, info); 335af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent} 336af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent 337af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurentstatus_t StreamInHalLocal::getMmapPosition(struct audio_mmap_position *position) { 338af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent if (mStream->get_mmap_position == NULL) return INVALID_OPERATION; 339af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent return mStream->get_mmap_position(mStream, position); 340af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent} 341af35aadb7ab558035b6cf45bd3930ecaa3a3b330Eric Laurent 3429ff780e58ff96ff98acaae4166bb218880bf9e73jiabinstatus_t StreamInHalLocal::getActiveMicrophones( 3439ff780e58ff96ff98acaae4166bb218880bf9e73jiabin std::vector<media::MicrophoneInfo> *microphones __unused) { 3449ff780e58ff96ff98acaae4166bb218880bf9e73jiabin return INVALID_OPERATION; 3459ff780e58ff96ff98acaae4166bb218880bf9e73jiabin} 3469ff780e58ff96ff98acaae4166bb218880bf9e73jiabin 3471dc98674f701dada94143b4d31b7221c58346c6cMikhail Naganov} // namespace android 348