AudioOutputDescriptor.cpp revision de80105c3f2db0eabd47640c49387ea3b44d4782
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" 24ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent#include "Volume.h" 25ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include "HwModule.h" 26ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie#include <media/AudioPolicy.h> 2756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 2853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie// A device mask for all audio output devices that are considered "remote" when evaluating 2953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie// active output devices in isStreamActiveRemotely() 3053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie#define APM_AUDIO_OUT_DEVICE_REMOTE_ALL AUDIO_DEVICE_OUT_REMOTE_SUBMIX 3153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 3256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivinamespace android { 3356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 34c75307b73d324d590d0dbc05b44bce9aa89b7145Eric LaurentAudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port, 35c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent AudioPolicyClientInterface *clientInterface) 36c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent : mPort(port), mDevice(AUDIO_DEVICE_NONE), 37c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mPatchHandle(0), mClientInterface(clientInterface), mId(0) 3856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 3956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi // clear usage count for all stream types 4056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (int i = 0; i < AUDIO_STREAM_CNT; i++) { 4156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mRefCount[i] = 0; 4256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mCurVolume[i] = -1.0; 4356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mMuteCount[i] = 0; 4456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mStopTime[i] = 0; 4556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 4656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (int i = 0; i < NUM_STRATEGIES; i++) { 4756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mStrategyMutedByDevice[i] = false; 4856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 49c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (port != NULL) { 50c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mSamplingRate = port->pickSamplingRate(); 51c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mFormat = port->pickFormat(); 52c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mChannelMask = port->pickChannelMask(); 53c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (port->mGains.size() > 0) { 54c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent port->mGains[0]->getDefaultConfig(&mGain); 5556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 5656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 5756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 5856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 5953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffieaudio_module_handle_t AudioOutputDescriptor::getModuleHandle() const 6053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 61c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mPort->getModuleHandle(); 6253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 6353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 64322b4d25387a04c9afebe998326d005bbdf17edeEric Laurentaudio_port_handle_t AudioOutputDescriptor::getId() const 65322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent{ 66322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent return mId; 67322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent} 68322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent 6956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Triviaudio_devices_t AudioOutputDescriptor::device() const 7056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 71c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mDevice; 7256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 7356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 74c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_devices_t AudioOutputDescriptor::supportedDevices() 7556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 76c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mDevice; 7756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 7856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 7956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivibool AudioOutputDescriptor::sharesHwModuleWith( 8056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi const sp<AudioOutputDescriptor> outputDesc) 8156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 82c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (outputDesc->isDuplicated()) { 83c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return sharesHwModuleWith(outputDesc->subOutput1()) || 84c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent sharesHwModuleWith(outputDesc->subOutput2()); 8556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } else { 86322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent return (getModuleHandle() == outputDesc->getModuleHandle()); 8756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 8856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 8956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 9056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream, 9156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi int delta) 9256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 9356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if ((delta + (int)mRefCount[stream]) < 0) { 9456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", 9556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi delta, stream, mRefCount[stream]); 9656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mRefCount[stream] = 0; 9756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return; 9856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 9956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mRefCount[stream] += delta; 10056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]); 10156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 10256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 10356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivibool AudioOutputDescriptor::isActive(uint32_t inPastMs) const 10456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 105ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie nsecs_t sysTime = 0; 106ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie if (inPastMs != 0) { 10756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi sysTime = systemTime(); 10856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 10956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 11056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (i == AUDIO_STREAM_PATCH) { 11156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi continue; 11256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 113ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie if (isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) { 11456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return true; 11556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 11656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 11756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return false; 11856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 11956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 12056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivibool AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream, 12153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie uint32_t inPastMs, 12253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie nsecs_t sysTime) const 12356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 12456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (mRefCount[stream] != 0) { 12556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return true; 12656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 12756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (inPastMs == 0) { 12856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return false; 12956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 13056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (sysTime == 0) { 13156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi sysTime = systemTime(); 13256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 13356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) { 13456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return true; 13556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 13656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return false; 13756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 13856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 139c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 140c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool AudioOutputDescriptor::isFixedVolume(audio_devices_t device __unused) 141c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 142c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return false; 143c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 144c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 145c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool AudioOutputDescriptor::setVolume(float volume, 146c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent audio_stream_type_t stream, 147c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent audio_devices_t device __unused, 148c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent uint32_t delayMs, 149c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent bool force) 150c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 151c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent // We actually change the volume if: 152c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent // - the float value returned by computeVolume() changed 153c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent // - the force flag is set 154c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (volume != mCurVolume[stream] || force) { 155c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent ALOGV("setVolume() for stream %d, volume %f, delay %d", stream, volume, delayMs); 156c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mCurVolume[stream] = volume; 157c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return true; 158c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 159c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return false; 160c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 161c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 16256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid AudioOutputDescriptor::toAudioPortConfig( 16356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi struct audio_port_config *dstConfig, 16456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi const struct audio_port_config *srcConfig) const 16556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 16656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK| 16756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN; 16856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (srcConfig != NULL) { 16956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi dstConfig->config_mask |= srcConfig->config_mask; 17056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 17156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig); 17256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 17356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi dstConfig->id = mId; 17456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi dstConfig->role = AUDIO_PORT_ROLE_SOURCE; 17556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi dstConfig->type = AUDIO_PORT_TYPE_MIX; 176322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent dstConfig->ext.mix.hw_module = getModuleHandle(); 17756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT; 17856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 17956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 18056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid AudioOutputDescriptor::toAudioPort( 18156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi struct audio_port *port) const 18256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 183c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mPort->toAudioPort(port); 18456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi port->id = mId; 185322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent port->ext.mix.hw_module = getModuleHandle(); 18656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 18756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 18856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivistatus_t AudioOutputDescriptor::dump(int fd) 18956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 19056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi const size_t SIZE = 256; 19156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi char buffer[SIZE]; 19256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi String8 result; 19356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 194c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent snprintf(buffer, SIZE, " ID: %d\n", mId); 19556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 19656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 19756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 19856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " Format: %08x\n", mFormat); 19956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 20056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 20156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 20256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " Devices %08x\n", device()); 20356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 20456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " Stream volume refCount muteCount\n"); 20556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 20656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 20756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n", 20856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi i, mCurVolume[i], mRefCount[i], mMuteCount[i]); 20956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 21056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 21156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi write(fd, result.string(), result.size()); 21256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 21356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return NO_ERROR; 21456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 21556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 216aa9811945f575614b3482d09e4d969792701cebbPaul McLeanvoid AudioOutputDescriptor::log(const char* indent) 217aa9811945f575614b3482d09e4d969792701cebbPaul McLean{ 218c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]", 219c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent indent, mId, mId, mSamplingRate, mFormat, mChannelMask); 220c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 221c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 222c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent// SwAudioOutputDescriptor implementation 223c75307b73d324d590d0dbc05b44bce9aa89b7145Eric LaurentSwAudioOutputDescriptor::SwAudioOutputDescriptor( 224c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const sp<IOProfile>& profile, AudioPolicyClientInterface *clientInterface) 225c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent : AudioOutputDescriptor(profile, clientInterface), 226c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mProfile(profile), mIoHandle(0), mLatency(0), 227c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mFlags((audio_output_flags_t)0), mPolicyMix(NULL), 228de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mOutput1(0), mOutput2(0), mDirectOpenCount(0), mGlobalRefCount(0) 229c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 230c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (profile != NULL) { 231c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mFlags = (audio_output_flags_t)profile->mFlags; 232c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 233c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 234c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 235c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid SwAudioOutputDescriptor::setIoHandle(audio_io_handle_t ioHandle) 236c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 237c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mId = AudioPort::getNextUniqueId(); 238c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mIoHandle = ioHandle; 239c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 240c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 241c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 242c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentstatus_t SwAudioOutputDescriptor::dump(int fd) 243c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 244c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const size_t SIZE = 256; 245c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent char buffer[SIZE]; 246c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent String8 result; 247c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 248c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent snprintf(buffer, SIZE, " Latency: %d\n", mLatency); 249c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent result.append(buffer); 250c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent snprintf(buffer, SIZE, " Flags %08x\n", mFlags); 251c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent result.append(buffer); 252c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent write(fd, result.string(), result.size()); 253c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 254c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent AudioOutputDescriptor::dump(fd); 255c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 256c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return NO_ERROR; 257c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 258c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 259c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_devices_t SwAudioOutputDescriptor::device() const 260c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 261c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (isDuplicated()) { 262c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice); 263c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } else { 264c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mDevice; 265c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 266aa9811945f575614b3482d09e4d969792701cebbPaul McLean} 267aa9811945f575614b3482d09e4d969792701cebbPaul McLean 268c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputDescriptor::sharesHwModuleWith( 269c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const sp<AudioOutputDescriptor> outputDesc) 270c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 271c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (isDuplicated()) { 272c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc); 273c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } else if (outputDesc->isDuplicated()){ 274c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return sharesHwModuleWith(outputDesc->subOutput1()) || 275c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent sharesHwModuleWith(outputDesc->subOutput2()); 276c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } else { 277c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return AudioOutputDescriptor::sharesHwModuleWith(outputDesc); 278c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 279c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 280c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 281c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_devices_t SwAudioOutputDescriptor::supportedDevices() 282c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 283c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (isDuplicated()) { 284c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices()); 285c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } else { 286c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mProfile->mSupportedDevices.types() ; 287c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 288c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 289c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 290c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentuint32_t SwAudioOutputDescriptor::latency() 291c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 292c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (isDuplicated()) { 293c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency; 294c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } else { 295c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mLatency; 296c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 297c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 298c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 299c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid SwAudioOutputDescriptor::changeRefCount(audio_stream_type_t stream, 300c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent int delta) 301c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 302c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent // forward usage count change to attached outputs 303c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (isDuplicated()) { 304c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mOutput1->changeRefCount(stream, delta); 305c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mOutput2->changeRefCount(stream, delta); 306c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 307c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent AudioOutputDescriptor::changeRefCount(stream, delta); 308de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 309de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi // handle stream-independent ref count 310de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi uint32_t oldGlobalRefCount = mGlobalRefCount; 311de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi if ((delta + (int)mGlobalRefCount) < 0) { 312de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi ALOGW("changeRefCount() invalid delta %d globalRefCount %d", delta, mGlobalRefCount); 313de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mGlobalRefCount = 0; 314de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } else { 315de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mGlobalRefCount += delta; 316de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } 317de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 0)) { 318de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi if ((mPolicyMix != NULL) && ((mPolicyMix->mFlags & MIX_FLAG_NOTIFY_ACTIVITY) != 0)) { 319de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mRegistrationId, 320de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi MIX_STATE_MIXING); 321de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } 322de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 323de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } else if ((oldGlobalRefCount > 0) && (mGlobalRefCount == 0)) { 324de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi if ((mPolicyMix != NULL) && ((mPolicyMix->mFlags & MIX_FLAG_NOTIFY_ACTIVITY) != 0)) { 325de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mRegistrationId, 326de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi MIX_STATE_IDLE); 327de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } 328de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } 329c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 330c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 331c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 332c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputDescriptor::isFixedVolume(audio_devices_t device) 333c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 334c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent // unit gain if rerouting to external policy 335c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) { 336c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (mPolicyMix != NULL) { 337c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent ALOGV("max gain when rerouting for output=%d", mIoHandle); 338c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return true; 339c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 340c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 341c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return false; 342c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 343c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 344c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid SwAudioOutputDescriptor::toAudioPortConfig( 345c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent struct audio_port_config *dstConfig, 346c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const struct audio_port_config *srcConfig) const 347c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 348c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 349c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle); 350c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig); 351c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 352c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent dstConfig->ext.mix.handle = mIoHandle; 353c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 354c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 355c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid SwAudioOutputDescriptor::toAudioPort( 356c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent struct audio_port *port) const 357c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 358c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle); 359c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 360c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent AudioOutputDescriptor::toAudioPort(port); 361c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 362c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent toAudioPortConfig(&port->active_config); 363c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent port->ext.mix.handle = mIoHandle; 364c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent port->ext.mix.latency_class = 365c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL; 366c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 367c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 368c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputDescriptor::setVolume(float volume, 369c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent audio_stream_type_t stream, 370c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent audio_devices_t device, 371c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent uint32_t delayMs, 372c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent bool force) 373c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 374c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force); 375c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 376c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (changed) { 377c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is 378c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent // enabled 379ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent float volume = Volume::DbToAmpl(mCurVolume[stream]); 380c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (stream == AUDIO_STREAM_BLUETOOTH_SCO) { 381c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mClientInterface->setStreamVolume( 382ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent AUDIO_STREAM_VOICE_CALL, volume, mIoHandle, delayMs); 383c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 384ffbc80f5908eaf67a033c6e93a343c39dd6894ebEric Laurent mClientInterface->setStreamVolume(stream, volume, mIoHandle, delayMs); 385c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 386c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return changed; 387c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 388c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 389c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent// SwAudioOutputCollection implementation 390c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 391c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const 39253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 39353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie nsecs_t sysTime = systemTime(); 39453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < this->size(); i++) { 395c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i); 39653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 39753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return true; 39853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 39953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 40053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return false; 40153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 40253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 403c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream, 40453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie uint32_t inPastMs) const 40553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 40653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie nsecs_t sysTime = systemTime(); 40753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 408c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 40953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && 41053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 41153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie // do not consider re routing (when the output is going to a dynamic policy) 41253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie // as "remote playback" 41353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (outputDesc->mPolicyMix == NULL) { 41453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return true; 41553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 41653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 41753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 41853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return false; 41953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 42053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 421c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const 42253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 42353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 424c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 42553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { 42653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return this->keyAt(i); 42753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 42853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 42953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return 0; 43053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 43153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 432c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentsp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const 43353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 43453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 435c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 43653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 43753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return outputDesc; 43853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 43953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 44053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return NULL; 44153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 44256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 443c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentsp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const 44453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 445c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent sp<SwAudioOutputDescriptor> outputDesc = NULL; 44653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 44753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie outputDesc = valueAt(i); 448322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent if (outputDesc->getId() == id) { 44953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie break; 45053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 45153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 45253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return outputDesc; 45353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 45453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 455c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const 45653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 45753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) { 45853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (s == (size_t) streamToIgnore) { 45953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie continue; 46053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 46153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 462c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 46353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (outputDesc->mRefCount[s] != 0) { 46453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return true; 46553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 46653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 46753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 46853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return false; 46953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 47053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 471c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_devices_t SwAudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const 47253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 473c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent sp<SwAudioOutputDescriptor> outputDesc = valueFor(handle); 47453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie audio_devices_t devices = outputDesc->mProfile->mSupportedDevices.types(); 47553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return devices; 47653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 47753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 47853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 479c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentstatus_t SwAudioOutputCollection::dump(int fd) const 48053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 48153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie const size_t SIZE = 256; 48253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie char buffer[SIZE]; 48353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 48453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie snprintf(buffer, SIZE, "\nOutputs dump:\n"); 48553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie write(fd, buffer, strlen(buffer)); 48653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 48753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i)); 48853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie write(fd, buffer, strlen(buffer)); 48953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie valueAt(i)->dump(fd); 49053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 49153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 49253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return NO_ERROR; 49353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 49456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 49556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}; //namespace android 496