AudioOutputDescriptor.cpp revision c75307b73d324d590d0dbc05b44bce9aa89b7145
156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi/* 256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Copyright (C) 2015 The Android Open Source Project 356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * 456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * you may not use this file except in compliance with the License. 656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * You may obtain a copy of the License at 756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * 856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * 1056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 1156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 1256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * See the License for the specific language governing permissions and 1456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi * limitations under the License. 1556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi */ 1656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 1756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi#define LOG_TAG "APM::AudioOutputDescriptor" 1856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi//#define LOG_NDEBUG 0 1956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 20c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent#include <AudioPolicyInterface.h> 21ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include "AudioOutputDescriptor.h" 22ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include "IOProfile.h" 2398cc191247388132b6fd8a4ecd07abd6e4c5a0edFrançois Gaffie#include "AudioGain.h" 24ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include "HwModule.h" 25ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include <media/AudioPolicy.h> 2656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 2753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie// A device mask for all audio output devices that are considered "remote" when evaluating 2853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie// active output devices in isStreamActiveRemotely() 2953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie#define APM_AUDIO_OUT_DEVICE_REMOTE_ALL AUDIO_DEVICE_OUT_REMOTE_SUBMIX 3053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 3156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivinamespace android { 3256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 33c75307b73d324d590d0dbc05b44bce9aa89b7145Eric LaurentAudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port, 34c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent AudioPolicyClientInterface *clientInterface) 35c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent : mPort(port), mDevice(AUDIO_DEVICE_NONE), 36c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mPatchHandle(0), mClientInterface(clientInterface), mId(0) 3756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 3856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi // clear usage count for all stream types 3956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 4056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mRefCount[i] = 0; 4156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mCurVolume[i] = -1.0; 4256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mMuteCount[i] = 0; 4356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mStopTime[i] = 0; 4456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 4556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (int i = 0; i < NUM_STRATEGIES; i++) { 4656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mStrategyMutedByDevice[i] = false; 4756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 48c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (port != NULL) { 49c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mSamplingRate = port->pickSamplingRate(); 50c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mFormat = port->pickFormat(); 51c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mChannelMask = port->pickChannelMask(); 52c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (port->mGains.size() > 0) { 53c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent port->mGains[0]->getDefaultConfig(&mGain); 5456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 5556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 5656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 5756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 5853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffieaudio_module_handle_t AudioOutputDescriptor::getModuleHandle() const 5953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 60c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mPort->getModuleHandle(); 6153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 6253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 63322b4d25387a04c9afebe998326d005bbdf17edeEric Laurentaudio_port_handle_t AudioOutputDescriptor::getId() const 64322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent{ 65322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent return mId; 66322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent} 67322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent 6856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Triviaudio_devices_t AudioOutputDescriptor::device() const 6956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 70c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mDevice; 7156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 7256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 73c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_devices_t AudioOutputDescriptor::supportedDevices() 7456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 75c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mDevice; 7656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 7756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 7856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivibool AudioOutputDescriptor::sharesHwModuleWith( 7956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi const sp<AudioOutputDescriptor> outputDesc) 8056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 81c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (outputDesc->isDuplicated()) { 82c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return sharesHwModuleWith(outputDesc->subOutput1()) || 83c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent sharesHwModuleWith(outputDesc->subOutput2()); 8456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } else { 85322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent return (getModuleHandle() == outputDesc->getModuleHandle()); 8656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 8756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 8856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 8956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream, 9056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi int delta) 9156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 9256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if ((delta + (int)mRefCount[stream]) < 0) { 9356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", 9456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi delta, stream, mRefCount[stream]); 9556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mRefCount[stream] = 0; 9656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return; 9756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 9856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mRefCount[stream] += delta; 9956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]); 10056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 10156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 10256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivibool AudioOutputDescriptor::isActive(uint32_t inPastMs) const 10356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 104ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie nsecs_t sysTime = 0; 105ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie if (inPastMs != 0) { 10656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi sysTime = systemTime(); 10756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 10856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 10956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (i == AUDIO_STREAM_PATCH) { 11056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi continue; 11156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 112ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie if (isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) { 11356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return true; 11456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 11556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 11656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return false; 11756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 11856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 11956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivibool AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream, 12053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie uint32_t inPastMs, 12153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie nsecs_t sysTime) const 12256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 12356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (mRefCount[stream] != 0) { 12456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return true; 12556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 12656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (inPastMs == 0) { 12756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return false; 12856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 12956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (sysTime == 0) { 13056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi sysTime = systemTime(); 13156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 13256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) { 13356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return true; 13456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 13556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return false; 13656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 13756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 138c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 139c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool AudioOutputDescriptor::isFixedVolume(audio_devices_t device __unused) 140c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 141c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return false; 142c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 143c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 144c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool AudioOutputDescriptor::setVolume(float volume, 145c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent audio_stream_type_t stream, 146c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent audio_devices_t device __unused, 147c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent uint32_t delayMs, 148c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent bool force) 149c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 150c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent // We actually change the volume if: 151c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent // - the float value returned by computeVolume() changed 152c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent // - the force flag is set 153c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (volume != mCurVolume[stream] || force) { 154c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent ALOGV("setVolume() for stream %d, volume %f, delay %d", stream, volume, delayMs); 155c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mCurVolume[stream] = volume; 156c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return true; 157c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 158c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return false; 159c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 160c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 16156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid AudioOutputDescriptor::toAudioPortConfig( 16256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi struct audio_port_config *dstConfig, 16356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi const struct audio_port_config *srcConfig) const 16456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 16556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK| 16656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN; 16756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (srcConfig != NULL) { 16856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi dstConfig->config_mask |= srcConfig->config_mask; 16956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 17056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig); 17156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 17256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi dstConfig->id = mId; 17356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi dstConfig->role = AUDIO_PORT_ROLE_SOURCE; 17456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi dstConfig->type = AUDIO_PORT_TYPE_MIX; 175322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent dstConfig->ext.mix.hw_module = getModuleHandle(); 17656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT; 17756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 17856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 17956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid AudioOutputDescriptor::toAudioPort( 18056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi struct audio_port *port) const 18156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 182c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mPort->toAudioPort(port); 18356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi port->id = mId; 184322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent port->ext.mix.hw_module = getModuleHandle(); 18556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 18656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 18756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivistatus_t AudioOutputDescriptor::dump(int fd) 18856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 18956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi const size_t SIZE = 256; 19056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi char buffer[SIZE]; 19156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi String8 result; 19256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 193c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent snprintf(buffer, SIZE, " ID: %d\n", mId); 19456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 19556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 19656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 19756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " Format: %08x\n", mFormat); 19856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 19956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 20056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 20156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " Devices %08x\n", device()); 20256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 20356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " Stream volume refCount muteCount\n"); 20456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 20556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 20656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n", 20756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi i, mCurVolume[i], mRefCount[i], mMuteCount[i]); 20856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 20956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 21056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi write(fd, result.string(), result.size()); 21156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 21256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return NO_ERROR; 21356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 21456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 215aa9811945f575614b3482d09e4d969792701cebbPaul McLeanvoid AudioOutputDescriptor::log(const char* indent) 216aa9811945f575614b3482d09e4d969792701cebbPaul McLean{ 217c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]", 218c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent indent, mId, mId, mSamplingRate, mFormat, mChannelMask); 219c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 220c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 221c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent// SwAudioOutputDescriptor implementation 222c75307b73d324d590d0dbc05b44bce9aa89b7145Eric LaurentSwAudioOutputDescriptor::SwAudioOutputDescriptor( 223c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const sp<IOProfile>& profile, AudioPolicyClientInterface *clientInterface) 224c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent : AudioOutputDescriptor(profile, clientInterface), 225c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mProfile(profile), mIoHandle(0), mLatency(0), 226c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mFlags((audio_output_flags_t)0), mPolicyMix(NULL), 227c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mOutput1(0), mOutput2(0), mDirectOpenCount(0) 228c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 229c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (profile != NULL) { 230c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mFlags = (audio_output_flags_t)profile->mFlags; 231c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 232c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 233c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 234c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid SwAudioOutputDescriptor::setIoHandle(audio_io_handle_t ioHandle) 235c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 236c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mId = AudioPort::getNextUniqueId(); 237c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mIoHandle = ioHandle; 238c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 239c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 240c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 241c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentstatus_t SwAudioOutputDescriptor::dump(int fd) 242c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 243c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const size_t SIZE = 256; 244c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent char buffer[SIZE]; 245c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent String8 result; 246c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 247c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent snprintf(buffer, SIZE, " Latency: %d\n", mLatency); 248c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent result.append(buffer); 249c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent snprintf(buffer, SIZE, " Flags %08x\n", mFlags); 250c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent result.append(buffer); 251c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent write(fd, result.string(), result.size()); 252c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 253c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent AudioOutputDescriptor::dump(fd); 254c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 255c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return NO_ERROR; 256c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 257c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 258c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_devices_t SwAudioOutputDescriptor::device() const 259c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 260c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (isDuplicated()) { 261c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice); 262c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } else { 263c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mDevice; 264c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 265aa9811945f575614b3482d09e4d969792701cebbPaul McLean} 266aa9811945f575614b3482d09e4d969792701cebbPaul McLean 267c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputDescriptor::sharesHwModuleWith( 268c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const sp<AudioOutputDescriptor> outputDesc) 269c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 270c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (isDuplicated()) { 271c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc); 272c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } else if (outputDesc->isDuplicated()){ 273c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return sharesHwModuleWith(outputDesc->subOutput1()) || 274c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent sharesHwModuleWith(outputDesc->subOutput2()); 275c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } else { 276c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return AudioOutputDescriptor::sharesHwModuleWith(outputDesc); 277c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 278c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 279c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 280c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_devices_t SwAudioOutputDescriptor::supportedDevices() 281c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 282c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (isDuplicated()) { 283c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices()); 284c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } else { 285c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mProfile->mSupportedDevices.types() ; 286c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 287c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 288c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 289c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentuint32_t SwAudioOutputDescriptor::latency() 290c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 291c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (isDuplicated()) { 292c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency; 293c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } else { 294c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mLatency; 295c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 296c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 297c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 298c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid SwAudioOutputDescriptor::changeRefCount(audio_stream_type_t stream, 299c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent int delta) 300c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 301c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent // forward usage count change to attached outputs 302c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (isDuplicated()) { 303c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mOutput1->changeRefCount(stream, delta); 304c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mOutput2->changeRefCount(stream, delta); 305c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 306c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent AudioOutputDescriptor::changeRefCount(stream, delta); 307c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 308c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 309c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 310c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputDescriptor::isFixedVolume(audio_devices_t device) 311c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 312c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent // unit gain if rerouting to external policy 313c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) { 314c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (mPolicyMix != NULL) { 315c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent ALOGV("max gain when rerouting for output=%d", mIoHandle); 316c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return true; 317c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 318c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 319c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return false; 320c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 321c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 322c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid SwAudioOutputDescriptor::toAudioPortConfig( 323c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent struct audio_port_config *dstConfig, 324c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const struct audio_port_config *srcConfig) const 325c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 326c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 327c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle); 328c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig); 329c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 330c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent dstConfig->ext.mix.handle = mIoHandle; 331c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 332c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 333c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid SwAudioOutputDescriptor::toAudioPort( 334c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent struct audio_port *port) const 335c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 336c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle); 337c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 338c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent AudioOutputDescriptor::toAudioPort(port); 339c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 340c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent toAudioPortConfig(&port->active_config); 341c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent port->ext.mix.handle = mIoHandle; 342c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent port->ext.mix.latency_class = 343c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL; 344c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 345c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 346c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputDescriptor::setVolume(float volume, 347c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent audio_stream_type_t stream, 348c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent audio_devices_t device, 349c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent uint32_t delayMs, 350c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent bool force) 351c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 352c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force); 353c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 354c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (changed) { 355c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is 356c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent // enabled 357c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (stream == AUDIO_STREAM_BLUETOOTH_SCO) { 358c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mClientInterface->setStreamVolume( 359c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent AUDIO_STREAM_VOICE_CALL, mCurVolume[stream], mIoHandle, delayMs); 360c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 361c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mClientInterface->setStreamVolume(stream, mCurVolume[stream], mIoHandle, delayMs); 362c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 363c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return changed; 364c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 365c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 366c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent// SwAudioOutputCollection implementation 367c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 368c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const 36953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 37053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie nsecs_t sysTime = systemTime(); 37153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < this->size(); i++) { 372c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i); 37353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 37453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return true; 37553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 37653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 37753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return false; 37853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 37953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 380c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream, 38153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie uint32_t inPastMs) const 38253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 38353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie nsecs_t sysTime = systemTime(); 38453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 385c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 38653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && 38753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 38853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie // do not consider re routing (when the output is going to a dynamic policy) 38953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie // as "remote playback" 39053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (outputDesc->mPolicyMix == NULL) { 39153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return true; 39253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 39353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 39453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 39553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return false; 39653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 39753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 398c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const 39953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 40053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 401c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 40253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { 40353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return this->keyAt(i); 40453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 40553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 40653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return 0; 40753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 40853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 409c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentsp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const 41053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 41153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 412c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 41353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 41453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return outputDesc; 41553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 41653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 41753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return NULL; 41853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 41956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 420c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentsp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const 42153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 422c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent sp<SwAudioOutputDescriptor> outputDesc = NULL; 42353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 42453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie outputDesc = valueAt(i); 425322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent if (outputDesc->getId() == id) { 42653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie break; 42753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 42853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 42953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return outputDesc; 43053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 43153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 432c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const 43353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 43453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) { 43553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (s == (size_t) streamToIgnore) { 43653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie continue; 43753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 43853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 439c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 44053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (outputDesc->mRefCount[s] != 0) { 44153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return true; 44253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 44353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 44453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 44553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return false; 44653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 44753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 448c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_devices_t SwAudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const 44953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 450c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent sp<SwAudioOutputDescriptor> outputDesc = valueFor(handle); 45153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie audio_devices_t devices = outputDesc->mProfile->mSupportedDevices.types(); 45253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return devices; 45353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 45453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 45553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 456c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentstatus_t SwAudioOutputCollection::dump(int fd) const 45753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 45853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie const size_t SIZE = 256; 45953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie char buffer[SIZE]; 46053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 46153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie snprintf(buffer, SIZE, "\nOutputs dump:\n"); 46253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie write(fd, buffer, strlen(buffer)); 46353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 46453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i)); 46553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie write(fd, buffer, strlen(buffer)); 46653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie valueAt(i)->dump(fd); 46753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 46853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 46953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return NO_ERROR; 47053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 47156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 47256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}; //namespace android 473