1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "APM::AudioOutputDescriptor"
18 //#define LOG_NDEBUG 0
19 
20 #include <AudioPolicyInterface.h>
21 #include "AudioOutputDescriptor.h"
22 #include "IOProfile.h"
23 #include "AudioGain.h"
24 #include "Volume.h"
25 #include "HwModule.h"
26 #include <media/AudioPolicy.h>
27 
28 // A device mask for all audio output devices that are considered "remote" when evaluating
29 // active output devices in isStreamActiveRemotely()
30 #define APM_AUDIO_OUT_DEVICE_REMOTE_ALL  AUDIO_DEVICE_OUT_REMOTE_SUBMIX
31 
32 namespace android {
33 
AudioOutputDescriptor(const sp<AudioPort> & port,AudioPolicyClientInterface * clientInterface)34 AudioOutputDescriptor::AudioOutputDescriptor(const sp<AudioPort>& port,
35                                              AudioPolicyClientInterface *clientInterface)
36     : mPort(port), mDevice(AUDIO_DEVICE_NONE),
37       mPatchHandle(0), mClientInterface(clientInterface), mId(0)
38 {
39     // clear usage count for all stream types
40     for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
41         mRefCount[i] = 0;
42         mCurVolume[i] = -1.0;
43         mMuteCount[i] = 0;
44         mStopTime[i] = 0;
45     }
46     for (int i = 0; i < NUM_STRATEGIES; i++) {
47         mStrategyMutedByDevice[i] = false;
48     }
49     if (port != NULL) {
50         mSamplingRate = port->pickSamplingRate();
51         mFormat = port->pickFormat();
52         mChannelMask = port->pickChannelMask();
53         if (port->mGains.size() > 0) {
54             port->mGains[0]->getDefaultConfig(&mGain);
55         }
56     }
57 }
58 
getModuleHandle() const59 audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const
60 {
61     return mPort->getModuleHandle();
62 }
63 
getId() const64 audio_port_handle_t AudioOutputDescriptor::getId() const
65 {
66     return mId;
67 }
68 
device() const69 audio_devices_t AudioOutputDescriptor::device() const
70 {
71     return mDevice;
72 }
73 
supportedDevices()74 audio_devices_t AudioOutputDescriptor::supportedDevices()
75 {
76     return mDevice;
77 }
78 
sharesHwModuleWith(const sp<AudioOutputDescriptor> outputDesc)79 bool AudioOutputDescriptor::sharesHwModuleWith(
80         const sp<AudioOutputDescriptor> outputDesc)
81 {
82     if (outputDesc->isDuplicated()) {
83         return sharesHwModuleWith(outputDesc->subOutput1()) ||
84                     sharesHwModuleWith(outputDesc->subOutput2());
85     } else {
86         return (getModuleHandle() == outputDesc->getModuleHandle());
87     }
88 }
89 
changeRefCount(audio_stream_type_t stream,int delta)90 void AudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
91                                                                    int delta)
92 {
93     if ((delta + (int)mRefCount[stream]) < 0) {
94         ALOGW("changeRefCount() invalid delta %d for stream %d, refCount %d",
95               delta, stream, mRefCount[stream]);
96         mRefCount[stream] = 0;
97         return;
98     }
99     mRefCount[stream] += delta;
100     ALOGV("changeRefCount() stream %d, count %d", stream, mRefCount[stream]);
101 }
102 
isActive(uint32_t inPastMs) const103 bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const
104 {
105     nsecs_t sysTime = 0;
106     if (inPastMs != 0) {
107         sysTime = systemTime();
108     }
109     for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
110         if (i == AUDIO_STREAM_PATCH) {
111             continue;
112         }
113         if (isStreamActive((audio_stream_type_t)i, inPastMs, sysTime)) {
114             return true;
115         }
116     }
117     return false;
118 }
119 
isStreamActive(audio_stream_type_t stream,uint32_t inPastMs,nsecs_t sysTime) const120 bool AudioOutputDescriptor::isStreamActive(audio_stream_type_t stream,
121                                            uint32_t inPastMs,
122                                            nsecs_t sysTime) const
123 {
124     if (mRefCount[stream] != 0) {
125         return true;
126     }
127     if (inPastMs == 0) {
128         return false;
129     }
130     if (sysTime == 0) {
131         sysTime = systemTime();
132     }
133     if (ns2ms(sysTime - mStopTime[stream]) < inPastMs) {
134         return true;
135     }
136     return false;
137 }
138 
139 
isFixedVolume(audio_devices_t device __unused)140 bool AudioOutputDescriptor::isFixedVolume(audio_devices_t device __unused)
141 {
142     return false;
143 }
144 
setVolume(float volume,audio_stream_type_t stream,audio_devices_t device __unused,uint32_t delayMs,bool force)145 bool AudioOutputDescriptor::setVolume(float volume,
146                                       audio_stream_type_t stream,
147                                       audio_devices_t device __unused,
148                                       uint32_t delayMs,
149                                       bool force)
150 {
151     // We actually change the volume if:
152     // - the float value returned by computeVolume() changed
153     // - the force flag is set
154     if (volume != mCurVolume[stream] || force) {
155         ALOGV("setVolume() for stream %d, volume %f, delay %d", stream, volume, delayMs);
156         mCurVolume[stream] = volume;
157         return true;
158     }
159     return false;
160 }
161 
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const162 void AudioOutputDescriptor::toAudioPortConfig(
163                                                  struct audio_port_config *dstConfig,
164                                                  const struct audio_port_config *srcConfig) const
165 {
166     dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
167                             AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
168     if (srcConfig != NULL) {
169         dstConfig->config_mask |= srcConfig->config_mask;
170     }
171     AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
172 
173     dstConfig->id = mId;
174     dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
175     dstConfig->type = AUDIO_PORT_TYPE_MIX;
176     dstConfig->ext.mix.hw_module = getModuleHandle();
177     dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
178 }
179 
toAudioPort(struct audio_port * port) const180 void AudioOutputDescriptor::toAudioPort(
181                                                     struct audio_port *port) const
182 {
183     mPort->toAudioPort(port);
184     port->id = mId;
185     port->ext.mix.hw_module = getModuleHandle();
186 }
187 
dump(int fd)188 status_t AudioOutputDescriptor::dump(int fd)
189 {
190     const size_t SIZE = 256;
191     char buffer[SIZE];
192     String8 result;
193 
194     snprintf(buffer, SIZE, " ID: %d\n", mId);
195     result.append(buffer);
196     snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
197     result.append(buffer);
198     snprintf(buffer, SIZE, " Format: %08x\n", mFormat);
199     result.append(buffer);
200     snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
201     result.append(buffer);
202     snprintf(buffer, SIZE, " Devices %08x\n", device());
203     result.append(buffer);
204     snprintf(buffer, SIZE, " Stream volume refCount muteCount\n");
205     result.append(buffer);
206     for (int i = 0; i < (int)AUDIO_STREAM_CNT; i++) {
207         snprintf(buffer, SIZE, " %02d     %.03f     %02d       %02d\n",
208                  i, mCurVolume[i], mRefCount[i], mMuteCount[i]);
209         result.append(buffer);
210     }
211     write(fd, result.string(), result.size());
212 
213     return NO_ERROR;
214 }
215 
log(const char * indent)216 void AudioOutputDescriptor::log(const char* indent)
217 {
218     ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]",
219           indent, mId, mId, mSamplingRate, mFormat, mChannelMask);
220 }
221 
222 // SwAudioOutputDescriptor implementation
SwAudioOutputDescriptor(const sp<IOProfile> & profile,AudioPolicyClientInterface * clientInterface)223 SwAudioOutputDescriptor::SwAudioOutputDescriptor(
224         const sp<IOProfile>& profile, AudioPolicyClientInterface *clientInterface)
225     : AudioOutputDescriptor(profile, clientInterface),
226     mProfile(profile), mIoHandle(0), mLatency(0),
227     mFlags((audio_output_flags_t)0), mPolicyMix(NULL),
228     mOutput1(0), mOutput2(0), mDirectOpenCount(0), mGlobalRefCount(0)
229 {
230     if (profile != NULL) {
231         mFlags = (audio_output_flags_t)profile->mFlags;
232     }
233 }
234 
setIoHandle(audio_io_handle_t ioHandle)235 void SwAudioOutputDescriptor::setIoHandle(audio_io_handle_t ioHandle)
236 {
237     mId = AudioPort::getNextUniqueId();
238     mIoHandle = ioHandle;
239 }
240 
241 
dump(int fd)242 status_t SwAudioOutputDescriptor::dump(int fd)
243 {
244     const size_t SIZE = 256;
245     char buffer[SIZE];
246     String8 result;
247 
248     snprintf(buffer, SIZE, " Latency: %d\n", mLatency);
249     result.append(buffer);
250     snprintf(buffer, SIZE, " Flags %08x\n", mFlags);
251     result.append(buffer);
252     write(fd, result.string(), result.size());
253 
254     AudioOutputDescriptor::dump(fd);
255 
256     return NO_ERROR;
257 }
258 
device() const259 audio_devices_t SwAudioOutputDescriptor::device() const
260 {
261     if (isDuplicated()) {
262         return (audio_devices_t)(mOutput1->mDevice | mOutput2->mDevice);
263     } else {
264         return mDevice;
265     }
266 }
267 
sharesHwModuleWith(const sp<AudioOutputDescriptor> outputDesc)268 bool SwAudioOutputDescriptor::sharesHwModuleWith(
269         const sp<AudioOutputDescriptor> outputDesc)
270 {
271     if (isDuplicated()) {
272         return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
273     } else if (outputDesc->isDuplicated()){
274         return sharesHwModuleWith(outputDesc->subOutput1()) ||
275                     sharesHwModuleWith(outputDesc->subOutput2());
276     } else {
277         return AudioOutputDescriptor::sharesHwModuleWith(outputDesc);
278     }
279 }
280 
supportedDevices()281 audio_devices_t SwAudioOutputDescriptor::supportedDevices()
282 {
283     if (isDuplicated()) {
284         return (audio_devices_t)(mOutput1->supportedDevices() | mOutput2->supportedDevices());
285     } else {
286         return mProfile->mSupportedDevices.types() ;
287     }
288 }
289 
latency()290 uint32_t SwAudioOutputDescriptor::latency()
291 {
292     if (isDuplicated()) {
293         return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
294     } else {
295         return mLatency;
296     }
297 }
298 
changeRefCount(audio_stream_type_t stream,int delta)299 void SwAudioOutputDescriptor::changeRefCount(audio_stream_type_t stream,
300                                                                    int delta)
301 {
302     // forward usage count change to attached outputs
303     if (isDuplicated()) {
304         mOutput1->changeRefCount(stream, delta);
305         mOutput2->changeRefCount(stream, delta);
306     }
307     AudioOutputDescriptor::changeRefCount(stream, delta);
308 
309     // handle stream-independent ref count
310     uint32_t oldGlobalRefCount = mGlobalRefCount;
311     if ((delta + (int)mGlobalRefCount) < 0) {
312         ALOGW("changeRefCount() invalid delta %d globalRefCount %d", delta, mGlobalRefCount);
313         mGlobalRefCount = 0;
314     } else {
315         mGlobalRefCount += delta;
316     }
317     if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 0)) {
318         if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
319         {
320             mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mRegistrationId,
321                     MIX_STATE_MIXING);
322         }
323 
324     } else if ((oldGlobalRefCount > 0) && (mGlobalRefCount == 0)) {
325         if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
326         {
327             mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mRegistrationId,
328                     MIX_STATE_IDLE);
329         }
330     }
331 }
332 
333 
isFixedVolume(audio_devices_t device)334 bool SwAudioOutputDescriptor::isFixedVolume(audio_devices_t device)
335 {
336     // unit gain if rerouting to external policy
337     if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX) {
338         if (mPolicyMix != NULL) {
339             ALOGV("max gain when rerouting for output=%d", mIoHandle);
340             return true;
341         }
342     }
343     return false;
344 }
345 
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const346 void SwAudioOutputDescriptor::toAudioPortConfig(
347                                                  struct audio_port_config *dstConfig,
348                                                  const struct audio_port_config *srcConfig) const
349 {
350 
351     ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
352     AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig);
353 
354     dstConfig->ext.mix.handle = mIoHandle;
355 }
356 
toAudioPort(struct audio_port * port) const357 void SwAudioOutputDescriptor::toAudioPort(
358                                                     struct audio_port *port) const
359 {
360     ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
361 
362     AudioOutputDescriptor::toAudioPort(port);
363 
364     toAudioPortConfig(&port->active_config);
365     port->ext.mix.handle = mIoHandle;
366     port->ext.mix.latency_class =
367             mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
368 }
369 
setVolume(float volume,audio_stream_type_t stream,audio_devices_t device,uint32_t delayMs,bool force)370 bool SwAudioOutputDescriptor::setVolume(float volume,
371                                         audio_stream_type_t stream,
372                                         audio_devices_t device,
373                                         uint32_t delayMs,
374                                         bool force)
375 {
376     bool changed = AudioOutputDescriptor::setVolume(volume, stream, device, delayMs, force);
377 
378     if (changed) {
379         // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is
380         // enabled
381         float volume = Volume::DbToAmpl(mCurVolume[stream]);
382         if (stream == AUDIO_STREAM_BLUETOOTH_SCO) {
383             mClientInterface->setStreamVolume(
384                     AUDIO_STREAM_VOICE_CALL, volume, mIoHandle, delayMs);
385         }
386         mClientInterface->setStreamVolume(stream, volume, mIoHandle, delayMs);
387     }
388     return changed;
389 }
390 
391 // SwAudioOutputCollection implementation
392 
isStreamActive(audio_stream_type_t stream,uint32_t inPastMs) const393 bool SwAudioOutputCollection::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
394 {
395     nsecs_t sysTime = systemTime();
396     for (size_t i = 0; i < this->size(); i++) {
397         const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
398         if (outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
399             return true;
400         }
401     }
402     return false;
403 }
404 
isStreamActiveRemotely(audio_stream_type_t stream,uint32_t inPastMs) const405 bool SwAudioOutputCollection::isStreamActiveRemotely(audio_stream_type_t stream,
406                                                    uint32_t inPastMs) const
407 {
408     nsecs_t sysTime = systemTime();
409     for (size_t i = 0; i < size(); i++) {
410         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
411         if (((outputDesc->device() & APM_AUDIO_OUT_DEVICE_REMOTE_ALL) != 0) &&
412                 outputDesc->isStreamActive(stream, inPastMs, sysTime)) {
413             // do not consider re routing (when the output is going to a dynamic policy)
414             // as "remote playback"
415             if (outputDesc->mPolicyMix == NULL) {
416                 return true;
417             }
418         }
419     }
420     return false;
421 }
422 
getA2dpOutput() const423 audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
424 {
425     for (size_t i = 0; i < size(); i++) {
426         sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
427         if (!outputDesc->isDuplicated() && outputDesc->device() & AUDIO_DEVICE_OUT_ALL_A2DP) {
428             return this->keyAt(i);
429         }
430     }
431     return 0;
432 }
433 
getPrimaryOutput() const434 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const
435 {
436     for (size_t i = 0; i < size(); i++) {
437         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
438         if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
439             return outputDesc;
440         }
441     }
442     return NULL;
443 }
444 
getOutputFromId(audio_port_handle_t id) const445 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
446 {
447     sp<SwAudioOutputDescriptor> outputDesc = NULL;
448     for (size_t i = 0; i < size(); i++) {
449         outputDesc = valueAt(i);
450         if (outputDesc->getId() == id) {
451             break;
452         }
453     }
454     return outputDesc;
455 }
456 
isAnyOutputActive(audio_stream_type_t streamToIgnore) const457 bool SwAudioOutputCollection::isAnyOutputActive(audio_stream_type_t streamToIgnore) const
458 {
459     for (size_t s = 0 ; s < AUDIO_STREAM_CNT ; s++) {
460         if (s == (size_t) streamToIgnore) {
461             continue;
462         }
463         for (size_t i = 0; i < size(); i++) {
464             const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
465             if (outputDesc->mRefCount[s] != 0) {
466                 return true;
467             }
468         }
469     }
470     return false;
471 }
472 
getSupportedDevices(audio_io_handle_t handle) const473 audio_devices_t SwAudioOutputCollection::getSupportedDevices(audio_io_handle_t handle) const
474 {
475     sp<SwAudioOutputDescriptor> outputDesc = valueFor(handle);
476     audio_devices_t devices = outputDesc->mProfile->mSupportedDevices.types();
477     return devices;
478 }
479 
480 
dump(int fd) const481 status_t SwAudioOutputCollection::dump(int fd) const
482 {
483     const size_t SIZE = 256;
484     char buffer[SIZE];
485 
486     snprintf(buffer, SIZE, "\nOutputs dump:\n");
487     write(fd, buffer, strlen(buffer));
488     for (size_t i = 0; i < size(); i++) {
489         snprintf(buffer, SIZE, "- Output %d dump:\n", keyAt(i));
490         write(fd, buffer, strlen(buffer));
491         valueAt(i)->dump(fd);
492     }
493 
494     return NO_ERROR;
495 }
496 
497 }; //namespace android
498