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), 37a13cde98a880341f0a56d91da6364b093fb5d24eGlenn Kasten mClientInterface(clientInterface), mPatchHandle(AUDIO_PATCH_HANDLE_NONE), 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) { 50112b0af826aeca45855690b9c105b2cdf9938bbeFrançois Gaffie port->pickAudioProfile(mSamplingRate, mChannelMask, mFormat); 51c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (port->mGains.size() > 0) { 52c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent port->mGains[0]->getDefaultConfig(&mGain); 5356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 5456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 5556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 5656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 5753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffieaudio_module_handle_t AudioOutputDescriptor::getModuleHandle() const 5853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 59c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mPort->getModuleHandle(); 6053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 6153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 62322b4d25387a04c9afebe998326d005bbdf17edeEric Laurentaudio_port_handle_t AudioOutputDescriptor::getId() const 63322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent{ 64322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent return mId; 65322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent} 66322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent 6756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Triviaudio_devices_t AudioOutputDescriptor::device() const 6856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 69c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mDevice; 7056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 7156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 72c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_devices_t AudioOutputDescriptor::supportedDevices() 7356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 74c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mDevice; 7556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 7656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 7756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivibool AudioOutputDescriptor::sharesHwModuleWith( 7856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi const sp<AudioOutputDescriptor> outputDesc) 7956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 80c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (outputDesc->isDuplicated()) { 81c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return sharesHwModuleWith(outputDesc->subOutput1()) || 82c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent sharesHwModuleWith(outputDesc->subOutput2()); 8356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } else { 84232f26f8b673973ffa463f80b08b731ffacc8785Eric Laurent return (getModuleHandle() == outputDesc->getModuleHandle()); 8556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 8656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 8756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 8856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream, 8956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi int delta) 9056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 9156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if ((delta + (int)mRefCount[stream]) < 0) { 9256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d", 9356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi delta, stream, mRefCount[stream]); 9456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mRefCount[stream] = 0; 9556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return; 9656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 9756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi mRefCount[stream] += delta; 9856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]); 9956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 10056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 10156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivibool AudioOutputDescriptor::isActive(uint32_t inPastMs) const 10256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 103ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie nsecs_t sysTime = 0; 104ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie if (inPastMs != 0) { 10556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi sysTime = systemTime(); 10656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 10756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 10856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (i == AUDIO_STREAM_PATCH) { 10956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi continue; 11056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 111ad3183e2d4cecd02f6261270a7ea1c68be0efa0fFrançois Gaffie if (isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) { 11256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return true; 11356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 11456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 11556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return false; 11656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 11756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 11856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivibool AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream, 11953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie uint32_t inPastMs, 12053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie nsecs_t sysTime) const 12156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 12256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (mRefCount[stream] != 0) { 12356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return true; 12456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 12556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (inPastMs == 0) { 12656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return false; 12756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 12856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (sysTime == 0) { 12956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi sysTime = systemTime(); 13056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 13156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) { 13256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return true; 13356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 13456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return false; 13556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 13656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 137c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 138c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool AudioOutputDescriptor::isFixedVolume(audio_devices_t device __unused) 139c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 140c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return false; 141c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 142c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 143c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool AudioOutputDescriptor::setVolume(float volume, 144c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent audio_stream_type_t stream, 145c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent audio_devices_t device __unused, 146c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent uint32_t delayMs, 147c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent bool force) 148c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 149c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent // We actually change the volume if: 150c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent // - the float value returned by computeVolume() changed 151c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent // - the force flag is set 152c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (volume != mCurVolume[stream] || force) { 153c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent ALOGV("setVolume() for stream %d, volume %f, delay %d", stream, volume, delayMs); 154c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mCurVolume[stream] = volume; 155c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return true; 156c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 157c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return false; 158c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 159c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 16056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid AudioOutputDescriptor::toAudioPortConfig( 16156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi struct audio_port_config *dstConfig, 16256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi const struct audio_port_config *srcConfig) const 16356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 16456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK| 16556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN; 16656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi if (srcConfig != NULL) { 16756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi dstConfig->config_mask |= srcConfig->config_mask; 16856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 16956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig); 17056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 17156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi dstConfig->id = mId; 17256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi dstConfig->role = AUDIO_PORT_ROLE_SOURCE; 17356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi dstConfig->type = AUDIO_PORT_TYPE_MIX; 174322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent dstConfig->ext.mix.hw_module = getModuleHandle(); 17556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT; 17656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 17756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 17856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivivoid AudioOutputDescriptor::toAudioPort( 17956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi struct audio_port *port) const 18056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 181c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mPort->toAudioPort(port); 18256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi port->id = mId; 183322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent port->ext.mix.hw_module = getModuleHandle(); 18456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 18556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 18656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivistatus_t AudioOutputDescriptor::dump(int fd) 18756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi{ 18856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi const size_t SIZE = 256; 18956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi char buffer[SIZE]; 19056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi String8 result; 19156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 192c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent snprintf(buffer, SIZE, " ID: %d\n", mId); 19356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 19456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate); 19556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 19656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " Format: %08x\n", mFormat); 19756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 19856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask); 19956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 20056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " Devices %08x\n", device()); 20156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 20256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " Stream volume refCount muteCount\n"); 20356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 20456ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) { 20556ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi snprintf(buffer, SIZE, " %02d %.03f %02d %02d\n", 20656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi i, mCurVolume[i], mRefCount[i], mMuteCount[i]); 20756ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi result.append(buffer); 20856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi } 20956ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi write(fd, result.string(), result.size()); 21056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 21156ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi return NO_ERROR; 21256ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi} 21356ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 214aa9811945f575614b3482d09e4d969792701cebbPaul McLeanvoid AudioOutputDescriptor::log(const char* indent) 215aa9811945f575614b3482d09e4d969792701cebbPaul McLean{ 216c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]", 217c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent indent, mId, mId, mSamplingRate, mFormat, mChannelMask); 218c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 219c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 220c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent// SwAudioOutputDescriptor implementation 221d60560af7cb559762593161c8202459cc01fb0f5Eric LaurentSwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile, 222d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent AudioPolicyClientInterface *clientInterface) 223c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent : AudioOutputDescriptor(profile, clientInterface), 224c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mProfile(profile), mIoHandle(0), mLatency(0), 225c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mFlags((audio_output_flags_t)0), mPolicyMix(NULL), 226de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mOutput1(0), mOutput2(0), mDirectOpenCount(0), mGlobalRefCount(0) 227c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 228c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (profile != NULL) { 229a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie mFlags = (audio_output_flags_t)profile->getFlags(); 230c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 231c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 232c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 233c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid SwAudioOutputDescriptor::setIoHandle(audio_io_handle_t ioHandle) 234c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 235c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mId = AudioPort::getNextUniqueId(); 236c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mIoHandle = ioHandle; 237c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 238c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 239c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 240c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentstatus_t SwAudioOutputDescriptor::dump(int fd) 241c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 242c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const size_t SIZE = 256; 243c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent char buffer[SIZE]; 244c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent String8 result; 245c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 246c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent snprintf(buffer, SIZE, " Latency: %d\n", mLatency); 247c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent result.append(buffer); 248c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent snprintf(buffer, SIZE, " Flags %08x\n", mFlags); 249c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent result.append(buffer); 250c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent write(fd, result.string(), result.size()); 251c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 252c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent AudioOutputDescriptor::dump(fd); 253c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 254c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return NO_ERROR; 255c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 256c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 257c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_devices_t SwAudioOutputDescriptor::device() const 258c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 259c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (isDuplicated()) { 260c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice); 261c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } else { 262c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mDevice; 263c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 264aa9811945f575614b3482d09e4d969792701cebbPaul McLean} 265aa9811945f575614b3482d09e4d969792701cebbPaul McLean 266c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputDescriptor::sharesHwModuleWith( 267c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const sp<AudioOutputDescriptor> outputDesc) 268c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 269c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (isDuplicated()) { 270c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc); 271c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } else if (outputDesc->isDuplicated()){ 272c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return sharesHwModuleWith(outputDesc->subOutput1()) || 273c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent sharesHwModuleWith(outputDesc->subOutput2()); 274c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } else { 275c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return AudioOutputDescriptor::sharesHwModuleWith(outputDesc); 276c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 277c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 278c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 279c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_devices_t SwAudioOutputDescriptor::supportedDevices() 280c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 281c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (isDuplicated()) { 282c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices()); 283c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } else { 284a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie return mProfile->getSupportedDevicesType(); 285c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 286c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 287c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 288c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentuint32_t SwAudioOutputDescriptor::latency() 289c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 290c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (isDuplicated()) { 291c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency; 292c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } else { 293c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent return mLatency; 294c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 295c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent} 296c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 297c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentvoid SwAudioOutputDescriptor::changeRefCount(audio_stream_type_t stream, 298c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent int delta) 299c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent{ 300c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent // forward usage count change to attached outputs 301c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent if (isDuplicated()) { 302c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mOutput1->changeRefCount(stream, delta); 303c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent mOutput2->changeRefCount(stream, delta); 304c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent } 305c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent AudioOutputDescriptor::changeRefCount(stream, delta); 306de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 307de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi // handle stream-independent ref count 308de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi uint32_t oldGlobalRefCount = mGlobalRefCount; 309de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi if ((delta + (int)mGlobalRefCount) < 0) { 310de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi ALOGW("changeRefCount() invalid delta %d globalRefCount %d", delta, mGlobalRefCount); 311de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mGlobalRefCount = 0; 312de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } else { 313de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi mGlobalRefCount += delta; 314de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } 315de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 0)) { 316f613d42b12389335b2ecf06df18d0d095d6bfd44Jean-Michel Trivi if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) 317f613d42b12389335b2ecf06df18d0d095d6bfd44Jean-Michel Trivi { 3187638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress, 319de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi MIX_STATE_MIXING); 320de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } 321de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi 322de80105c3f2db0eabd47640c49387ea3b44d4782Jean-Michel Trivi } else if ((oldGlobalRefCount > 0) && (mGlobalRefCount == 0)) { 323f613d42b12389335b2ecf06df18d0d095d6bfd44Jean-Michel Trivi if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) 324f613d42b12389335b2ecf06df18d0d095d6bfd44Jean-Michel Trivi { 3257638ca29e8400a19524adb982e9d22c02786de82Jean-Michel Trivi mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress, 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 389d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent// HwAudioOutputDescriptor implementation 390d60560af7cb559762593161c8202459cc01fb0f5Eric LaurentHwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<AudioSourceDescriptor>& source, 391d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent AudioPolicyClientInterface *clientInterface) 392d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent : AudioOutputDescriptor(source->mDevice, clientInterface), 393d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent mSource(source) 394d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{ 395d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent} 396d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent 397d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentstatus_t HwAudioOutputDescriptor::dump(int fd) 398d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{ 399d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent const size_t SIZE = 256; 400d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent char buffer[SIZE]; 401d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent String8 result; 402d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent 403d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent AudioOutputDescriptor::dump(fd); 404d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent 405d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent snprintf(buffer, SIZE, "Source:\n"); 406d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent result.append(buffer); 407d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent write(fd, result.string(), result.size()); 408d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent mSource->dump(fd); 409d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent 410d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent return NO_ERROR; 411d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent} 412d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent 413d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentaudio_devices_t HwAudioOutputDescriptor::supportedDevices() 414d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{ 415d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent return mDevice; 416d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent} 417d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent 418d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentvoid HwAudioOutputDescriptor::toAudioPortConfig( 419d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent struct audio_port_config *dstConfig, 420d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent const struct audio_port_config *srcConfig) const 421d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{ 422d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent mSource->mDevice->toAudioPortConfig(dstConfig, srcConfig); 423d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent} 424d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent 425d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentvoid HwAudioOutputDescriptor::toAudioPort( 426d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent struct audio_port *port) const 427d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{ 428d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent mSource->mDevice->toAudioPort(port); 429d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent} 430d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent 431d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent 432d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentbool HwAudioOutputDescriptor::setVolume(float volume, 433d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent audio_stream_type_t stream, 434d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent audio_devices_t device, 435d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent uint32_t delayMs, 436d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent bool force) 437d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{ 438d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force); 439d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent 440d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent if (changed) { 441d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent // TODO: use gain controller on source device if any to adjust volume 442d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent } 443d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent return changed; 444d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent} 445c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent 446d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent// SwAudioOutputCollection implementation 447c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const 44853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 44953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie nsecs_t sysTime = systemTime(); 45053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < this->size(); i++) { 451c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i); 45253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 45353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return true; 45453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 45553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 45653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return false; 45753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 45853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 459c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream, 46053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie uint32_t inPastMs) const 46153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 46253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie nsecs_t sysTime = systemTime(); 46353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 464c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 46553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) && 46653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 46753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie // do not consider re routing (when the output is going to a dynamic policy) 46853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie // as "remote playback" 46953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (outputDesc->mPolicyMix == NULL) { 47053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return true; 47153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 47253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 47353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 47453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return false; 47553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 47653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 477c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const 47853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 47953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 480c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 48153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) { 48253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return this->keyAt(i); 48353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 48453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 48553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return 0; 48653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 48753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 488c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentsp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const 48953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 49053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 491c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 49253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) { 49353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return outputDesc; 49453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 49553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 49653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return NULL; 49753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 49856ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 499c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentsp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const 50053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 501c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent sp<SwAudioOutputDescriptor> outputDesc = NULL; 50253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 50353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie outputDesc = valueAt(i); 504322b4d25387a04c9afebe998326d005bbdf17edeEric Laurent if (outputDesc->getId() == id) { 50553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie break; 50653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 50753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 50853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return outputDesc; 50953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 51053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 511c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentbool SwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const 51253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 51353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) { 51453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (s == (size_t) streamToIgnore) { 51553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie continue; 51653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 51753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 518c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i); 51953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie if (outputDesc->mRefCount[s] != 0) { 52053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return true; 52153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 52253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 52353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 52453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return false; 52553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 52653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 527c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentaudio_devices_t SwAudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const 52853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 529c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurent sp<SwAudioOutputDescriptor> outputDesc = valueFor(handle); 530a8ecc2c72ca26389bd6b0162181d60aaeaca8149François Gaffie audio_devices_t devices = outputDesc->mProfile->getSupportedDevicesType(); 53153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return devices; 53253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 53353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 53453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 535c75307b73d324d590d0dbc05b44bce9aa89b7145Eric Laurentstatus_t SwAudioOutputCollection::dump(int fd) const 53653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie{ 53753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie const size_t SIZE = 256; 53853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie char buffer[SIZE]; 53953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 54053615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie snprintf(buffer, SIZE, "\nOutputs dump:\n"); 54153615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie write(fd, buffer, strlen(buffer)); 54253615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie for (size_t i = 0; i < size(); i++) { 54353615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i)); 54453615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie write(fd, buffer, strlen(buffer)); 54553615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie valueAt(i)->dump(fd); 54653615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie } 54753615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie 54853615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie return NO_ERROR; 54953615e29c99c5e9d2ca77aaefd7bf5c770513120François Gaffie} 55056ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi 551d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent// HwAudioOutputCollection implementation 552d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentbool HwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const 553d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{ 554d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent nsecs_t sysTime = systemTime(); 555d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent for (size_t i = 0; i < this->size(); i++) { 556d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent const sp<HwAudioOutputDescriptor> outputDesc = this->valueAt(i); 557d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) { 558d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent return true; 559d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent } 560d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent } 561d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent return false; 562d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent} 563d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent 564d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentbool HwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const 565d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{ 566d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) { 567d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent if (s == (size_t) streamToIgnore) { 568d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent continue; 569d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent } 570d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent for (size_t i = 0; i < size(); i++) { 571d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent const sp<HwAudioOutputDescriptor> outputDesc = valueAt(i); 572d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent if (outputDesc->mRefCount[s] != 0) { 573d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent return true; 574d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent } 575d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent } 576d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent } 577d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent return false; 578d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent} 579d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent 580d60560af7cb559762593161c8202459cc01fb0f5Eric Laurentstatus_t HwAudioOutputCollection::dump(int fd) const 581d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent{ 582d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent const size_t SIZE = 256; 583d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent char buffer[SIZE]; 584d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent 585d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent snprintf(buffer, SIZE, "\nOutputs dump:\n"); 586d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent write(fd, buffer, strlen(buffer)); 587d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent for (size_t i = 0; i < size(); i++) { 588d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i)); 589d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent write(fd, buffer, strlen(buffer)); 590d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent valueAt(i)->dump(fd); 591d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent } 592d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent 593d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent return NO_ERROR; 594d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent} 595d60560af7cb559762593161c8202459cc01fb0f5Eric Laurent 59656ec4ffcbae8aeac6c5245fc7b825d02e2e6cefdJean-Michel Trivi}; //namespace android 597