AudioPolicyInterfaceImpl.cpp revision 8c7e6dac6f5eb38cef627dab92eac8b38513450c
1/*
2 * Copyright (C) 2009 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 "AudioPolicyIntefaceImpl"
18//#define LOG_NDEBUG 0
19
20#include <utils/Log.h>
21#include "AudioPolicyService.h"
22#include "ServiceUtilities.h"
23
24namespace android {
25
26
27// ----------------------------------------------------------------------------
28
29status_t AudioPolicyService::setDeviceConnectionState(audio_devices_t device,
30                                                  audio_policy_dev_state_t state,
31                                                  const char *device_address,
32                                                  const char *device_name)
33{
34    if (mAudioPolicyManager == NULL) {
35        return NO_INIT;
36    }
37    if (!settingsAllowed()) {
38        return PERMISSION_DENIED;
39    }
40    if (!audio_is_output_device(device) && !audio_is_input_device(device)) {
41        return BAD_VALUE;
42    }
43    if (state != AUDIO_POLICY_DEVICE_STATE_AVAILABLE &&
44            state != AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) {
45        return BAD_VALUE;
46    }
47
48    ALOGV("setDeviceConnectionState()");
49    Mutex::Autolock _l(mLock);
50    return mAudioPolicyManager->setDeviceConnectionState(device, state,
51                                                         device_address, device_name);
52}
53
54audio_policy_dev_state_t AudioPolicyService::getDeviceConnectionState(
55                                                              audio_devices_t device,
56                                                              const char *device_address)
57{
58    if (mAudioPolicyManager == NULL) {
59        return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE;
60    }
61    return mAudioPolicyManager->getDeviceConnectionState(device,
62                                                      device_address);
63}
64
65status_t AudioPolicyService::setPhoneState(audio_mode_t state)
66{
67    if (mAudioPolicyManager == NULL) {
68        return NO_INIT;
69    }
70    if (!settingsAllowed()) {
71        return PERMISSION_DENIED;
72    }
73    if (uint32_t(state) >= AUDIO_MODE_CNT) {
74        return BAD_VALUE;
75    }
76
77    ALOGV("setPhoneState()");
78
79    // TODO: check if it is more appropriate to do it in platform specific policy manager
80    AudioSystem::setMode(state);
81
82    Mutex::Autolock _l(mLock);
83    mAudioPolicyManager->setPhoneState(state);
84    mPhoneState = state;
85    return NO_ERROR;
86}
87
88audio_mode_t AudioPolicyService::getPhoneState()
89{
90    Mutex::Autolock _l(mLock);
91    return mPhoneState;
92}
93
94status_t AudioPolicyService::setForceUse(audio_policy_force_use_t usage,
95                                         audio_policy_forced_cfg_t config)
96{
97    if (mAudioPolicyManager == NULL) {
98        return NO_INIT;
99    }
100    if (!settingsAllowed()) {
101        return PERMISSION_DENIED;
102    }
103    if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
104        return BAD_VALUE;
105    }
106    if (config < 0 || config >= AUDIO_POLICY_FORCE_CFG_CNT) {
107        return BAD_VALUE;
108    }
109    ALOGV("setForceUse()");
110    Mutex::Autolock _l(mLock);
111    mAudioPolicyManager->setForceUse(usage, config);
112    return NO_ERROR;
113}
114
115audio_policy_forced_cfg_t AudioPolicyService::getForceUse(audio_policy_force_use_t usage)
116{
117    if (mAudioPolicyManager == NULL) {
118        return AUDIO_POLICY_FORCE_NONE;
119    }
120    if (usage < 0 || usage >= AUDIO_POLICY_FORCE_USE_CNT) {
121        return AUDIO_POLICY_FORCE_NONE;
122    }
123    return mAudioPolicyManager->getForceUse(usage);
124}
125
126audio_io_handle_t AudioPolicyService::getOutput(audio_stream_type_t stream,
127                                    uint32_t samplingRate,
128                                    audio_format_t format,
129                                    audio_channel_mask_t channelMask,
130                                    audio_output_flags_t flags,
131                                    const audio_offload_info_t *offloadInfo)
132{
133    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
134        return AUDIO_IO_HANDLE_NONE;
135    }
136    if (mAudioPolicyManager == NULL) {
137        return AUDIO_IO_HANDLE_NONE;
138    }
139    ALOGV("getOutput()");
140    Mutex::Autolock _l(mLock);
141    return mAudioPolicyManager->getOutput(stream, samplingRate,
142                                    format, channelMask, flags, offloadInfo);
143}
144
145status_t AudioPolicyService::getOutputForAttr(const audio_attributes_t *attr,
146                                              audio_io_handle_t *output,
147                                              audio_session_t session,
148                                              audio_stream_type_t *stream,
149                                              uid_t uid,
150                                              uint32_t samplingRate,
151                                              audio_format_t format,
152                                              audio_channel_mask_t channelMask,
153                                              audio_output_flags_t flags,
154                                              audio_port_handle_t selectedDeviceId,
155                                              const audio_offload_info_t *offloadInfo)
156{
157    if (mAudioPolicyManager == NULL) {
158        return NO_INIT;
159    }
160    ALOGV("getOutput()");
161    Mutex::Autolock _l(mLock);
162
163    // if the caller is us, trust the specified uid
164    if (IPCThreadState::self()->getCallingPid() != getpid_cached || uid == (uid_t)-1) {
165        uid_t newclientUid = IPCThreadState::self()->getCallingUid();
166        if (uid != (uid_t)-1 && uid != newclientUid) {
167            ALOGW("%s uid %d tried to pass itself off as %d", __FUNCTION__, newclientUid, uid);
168        }
169        uid = newclientUid;
170    }
171    return mAudioPolicyManager->getOutputForAttr(attr, output, session, stream, uid, samplingRate,
172                                    format, channelMask, flags, selectedDeviceId, offloadInfo);
173}
174
175status_t AudioPolicyService::startOutput(audio_io_handle_t output,
176                                         audio_stream_type_t stream,
177                                         audio_session_t session)
178{
179    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
180        return BAD_VALUE;
181    }
182    if (mAudioPolicyManager == NULL) {
183        return NO_INIT;
184    }
185    ALOGV("startOutput()");
186    sp<AudioPolicyEffects>audioPolicyEffects;
187    {
188        Mutex::Autolock _l(mLock);
189        audioPolicyEffects = mAudioPolicyEffects;
190    }
191    if (audioPolicyEffects != 0) {
192        // create audio processors according to stream
193        status_t status = audioPolicyEffects->addOutputSessionEffects(output, stream, session);
194        if (status != NO_ERROR && status != ALREADY_EXISTS) {
195            ALOGW("Failed to add effects on session %d", session);
196        }
197    }
198    Mutex::Autolock _l(mLock);
199    return mAudioPolicyManager->startOutput(output, stream, session);
200}
201
202status_t AudioPolicyService::stopOutput(audio_io_handle_t output,
203                                        audio_stream_type_t stream,
204                                        audio_session_t session)
205{
206    if (uint32_t(stream) >= AUDIO_STREAM_CNT) {
207        return BAD_VALUE;
208    }
209    if (mAudioPolicyManager == NULL) {
210        return NO_INIT;
211    }
212    ALOGV("stopOutput()");
213    mOutputCommandThread->stopOutputCommand(output, stream, session);
214    return NO_ERROR;
215}
216
217status_t  AudioPolicyService::doStopOutput(audio_io_handle_t output,
218                                      audio_stream_type_t stream,
219                                      audio_session_t session)
220{
221    ALOGV("doStopOutput from tid %d", gettid());
222    sp<AudioPolicyEffects>audioPolicyEffects;
223    {
224        Mutex::Autolock _l(mLock);
225        audioPolicyEffects = mAudioPolicyEffects;
226    }
227    if (audioPolicyEffects != 0) {
228        // release audio processors from the stream
229        status_t status = audioPolicyEffects->releaseOutputSessionEffects(output, stream, session);
230        if (status != NO_ERROR && status != ALREADY_EXISTS) {
231            ALOGW("Failed to release effects on session %d", session);
232        }
233    }
234    Mutex::Autolock _l(mLock);
235    return mAudioPolicyManager->stopOutput(output, stream, session);
236}
237
238void AudioPolicyService::releaseOutput(audio_io_handle_t output,
239                                       audio_stream_type_t stream,
240                                       audio_session_t session)
241{
242    if (mAudioPolicyManager == NULL) {
243        return;
244    }
245    ALOGV("releaseOutput()");
246    mOutputCommandThread->releaseOutputCommand(output, stream, session);
247}
248
249void AudioPolicyService::doReleaseOutput(audio_io_handle_t output,
250                                         audio_stream_type_t stream,
251                                         audio_session_t session)
252{
253    ALOGV("doReleaseOutput from tid %d", gettid());
254    Mutex::Autolock _l(mLock);
255    mAudioPolicyManager->releaseOutput(output, stream, session);
256}
257
258status_t AudioPolicyService::getInputForAttr(const audio_attributes_t *attr,
259                                             audio_io_handle_t *input,
260                                             audio_session_t session,
261                                             uid_t uid,
262                                             uint32_t samplingRate,
263                                             audio_format_t format,
264                                             audio_channel_mask_t channelMask,
265                                             audio_input_flags_t flags,
266                                             audio_port_handle_t selectedDeviceId)
267{
268    if (mAudioPolicyManager == NULL) {
269        return NO_INIT;
270    }
271    // already checked by client, but double-check in case the client wrapper is bypassed
272    if (attr->source >= AUDIO_SOURCE_CNT && attr->source != AUDIO_SOURCE_HOTWORD &&
273        attr->source != AUDIO_SOURCE_FM_TUNER) {
274        return BAD_VALUE;
275    }
276
277    if ((attr->source == AUDIO_SOURCE_HOTWORD) && !captureHotwordAllowed()) {
278        return BAD_VALUE;
279    }
280    sp<AudioPolicyEffects>audioPolicyEffects;
281    status_t status;
282    AudioPolicyInterface::input_type_t inputType;
283    // if the caller is us, trust the specified uid
284    if (IPCThreadState::self()->getCallingPid() != getpid_cached || uid == (uid_t)-1) {
285        uid_t newclientUid = IPCThreadState::self()->getCallingUid();
286        if (uid != (uid_t)-1 && uid != newclientUid) {
287            ALOGW("%s uid %d tried to pass itself off as %d", __FUNCTION__, newclientUid, uid);
288        }
289        uid = newclientUid;
290    }
291
292    {
293        Mutex::Autolock _l(mLock);
294        // the audio_in_acoustics_t parameter is ignored by get_input()
295        status = mAudioPolicyManager->getInputForAttr(attr, input, session, uid,
296                                                     samplingRate, format, channelMask,
297                                                     flags, selectedDeviceId,
298                                                     &inputType);
299        audioPolicyEffects = mAudioPolicyEffects;
300
301        if (status == NO_ERROR) {
302            // enforce permission (if any) required for each type of input
303            switch (inputType) {
304            case AudioPolicyInterface::API_INPUT_LEGACY:
305                break;
306            case AudioPolicyInterface::API_INPUT_MIX_CAPTURE:
307                if (!captureAudioOutputAllowed()) {
308                    ALOGE("getInputForAttr() permission denied: capture not allowed");
309                    status = PERMISSION_DENIED;
310                }
311                break;
312            case AudioPolicyInterface::API_INPUT_MIX_EXT_POLICY_REROUTE:
313                if (!modifyAudioRoutingAllowed()) {
314                    ALOGE("getInputForAttr() permission denied: modify audio routing not allowed");
315                    status = PERMISSION_DENIED;
316                }
317                break;
318            case AudioPolicyInterface::API_INPUT_INVALID:
319            default:
320                LOG_ALWAYS_FATAL("getInputForAttr() encountered an invalid input type %d",
321                        (int)inputType);
322            }
323        }
324
325        if (status != NO_ERROR) {
326            if (status == PERMISSION_DENIED) {
327                mAudioPolicyManager->releaseInput(*input, session);
328            }
329            return status;
330        }
331    }
332
333    if (audioPolicyEffects != 0) {
334        // create audio pre processors according to input source
335        status_t status = audioPolicyEffects->addInputEffects(*input, attr->source, session);
336        if (status != NO_ERROR && status != ALREADY_EXISTS) {
337            ALOGW("Failed to add effects on input %d", *input);
338        }
339    }
340    return NO_ERROR;
341}
342
343status_t AudioPolicyService::startInput(audio_io_handle_t input,
344                                        audio_session_t session)
345{
346    if (mAudioPolicyManager == NULL) {
347        return NO_INIT;
348    }
349    Mutex::Autolock _l(mLock);
350
351    return mAudioPolicyManager->startInput(input, session);
352}
353
354status_t AudioPolicyService::stopInput(audio_io_handle_t input,
355                                       audio_session_t session)
356{
357    if (mAudioPolicyManager == NULL) {
358        return NO_INIT;
359    }
360    Mutex::Autolock _l(mLock);
361
362    return mAudioPolicyManager->stopInput(input, session);
363}
364
365void AudioPolicyService::releaseInput(audio_io_handle_t input,
366                                      audio_session_t session)
367{
368    if (mAudioPolicyManager == NULL) {
369        return;
370    }
371    sp<AudioPolicyEffects>audioPolicyEffects;
372    {
373        Mutex::Autolock _l(mLock);
374        mAudioPolicyManager->releaseInput(input, session);
375        audioPolicyEffects = mAudioPolicyEffects;
376    }
377    if (audioPolicyEffects != 0) {
378        // release audio processors from the input
379        status_t status = audioPolicyEffects->releaseInputEffects(input);
380        if(status != NO_ERROR) {
381            ALOGW("Failed to release effects on input %d", input);
382        }
383    }
384}
385
386status_t AudioPolicyService::initStreamVolume(audio_stream_type_t stream,
387                                            int indexMin,
388                                            int indexMax)
389{
390    if (mAudioPolicyManager == NULL) {
391        return NO_INIT;
392    }
393    if (!settingsAllowed()) {
394        return PERMISSION_DENIED;
395    }
396    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
397        return BAD_VALUE;
398    }
399    Mutex::Autolock _l(mLock);
400    mAudioPolicyManager->initStreamVolume(stream, indexMin, indexMax);
401    return NO_ERROR;
402}
403
404status_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream,
405                                                  int index,
406                                                  audio_devices_t device)
407{
408    if (mAudioPolicyManager == NULL) {
409        return NO_INIT;
410    }
411    if (!settingsAllowed()) {
412        return PERMISSION_DENIED;
413    }
414    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
415        return BAD_VALUE;
416    }
417    Mutex::Autolock _l(mLock);
418    return mAudioPolicyManager->setStreamVolumeIndex(stream,
419                                                    index,
420                                                    device);
421}
422
423status_t AudioPolicyService::getStreamVolumeIndex(audio_stream_type_t stream,
424                                                  int *index,
425                                                  audio_devices_t device)
426{
427    if (mAudioPolicyManager == NULL) {
428        return NO_INIT;
429    }
430    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
431        return BAD_VALUE;
432    }
433    Mutex::Autolock _l(mLock);
434    return mAudioPolicyManager->getStreamVolumeIndex(stream,
435                                                    index,
436                                                    device);
437}
438
439uint32_t AudioPolicyService::getStrategyForStream(audio_stream_type_t stream)
440{
441    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
442        return 0;
443    }
444    if (mAudioPolicyManager == NULL) {
445        return 0;
446    }
447    return mAudioPolicyManager->getStrategyForStream(stream);
448}
449
450//audio policy: use audio_device_t appropriately
451
452audio_devices_t AudioPolicyService::getDevicesForStream(audio_stream_type_t stream)
453{
454    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
455        return AUDIO_DEVICE_NONE;
456    }
457    if (mAudioPolicyManager == NULL) {
458        return AUDIO_DEVICE_NONE;
459    }
460    return mAudioPolicyManager->getDevicesForStream(stream);
461}
462
463audio_io_handle_t AudioPolicyService::getOutputForEffect(const effect_descriptor_t *desc)
464{
465    // FIXME change return type to status_t, and return NO_INIT here
466    if (mAudioPolicyManager == NULL) {
467        return 0;
468    }
469    Mutex::Autolock _l(mLock);
470    return mAudioPolicyManager->getOutputForEffect(desc);
471}
472
473status_t AudioPolicyService::registerEffect(const effect_descriptor_t *desc,
474                                audio_io_handle_t io,
475                                uint32_t strategy,
476                                int session,
477                                int id)
478{
479    if (mAudioPolicyManager == NULL) {
480        return NO_INIT;
481    }
482    return mAudioPolicyManager->registerEffect(desc, io, strategy, session, id);
483}
484
485status_t AudioPolicyService::unregisterEffect(int id)
486{
487    if (mAudioPolicyManager == NULL) {
488        return NO_INIT;
489    }
490    return mAudioPolicyManager->unregisterEffect(id);
491}
492
493status_t AudioPolicyService::setEffectEnabled(int id, bool enabled)
494{
495    if (mAudioPolicyManager == NULL) {
496        return NO_INIT;
497    }
498    return mAudioPolicyManager->setEffectEnabled(id, enabled);
499}
500
501bool AudioPolicyService::isStreamActive(audio_stream_type_t stream, uint32_t inPastMs) const
502{
503    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
504        return false;
505    }
506    if (mAudioPolicyManager == NULL) {
507        return false;
508    }
509    Mutex::Autolock _l(mLock);
510    return mAudioPolicyManager->isStreamActive(stream, inPastMs);
511}
512
513bool AudioPolicyService::isStreamActiveRemotely(audio_stream_type_t stream, uint32_t inPastMs) const
514{
515    if (uint32_t(stream) >= AUDIO_STREAM_PUBLIC_CNT) {
516        return false;
517    }
518    if (mAudioPolicyManager == NULL) {
519        return false;
520    }
521    Mutex::Autolock _l(mLock);
522    return mAudioPolicyManager->isStreamActiveRemotely(stream, inPastMs);
523}
524
525bool AudioPolicyService::isSourceActive(audio_source_t source) const
526{
527    if (mAudioPolicyManager == NULL) {
528        return false;
529    }
530    Mutex::Autolock _l(mLock);
531    return mAudioPolicyManager->isSourceActive(source);
532}
533
534status_t AudioPolicyService::queryDefaultPreProcessing(int audioSession,
535                                                       effect_descriptor_t *descriptors,
536                                                       uint32_t *count)
537{
538    if (mAudioPolicyManager == NULL) {
539        *count = 0;
540        return NO_INIT;
541    }
542    sp<AudioPolicyEffects>audioPolicyEffects;
543    {
544        Mutex::Autolock _l(mLock);
545        audioPolicyEffects = mAudioPolicyEffects;
546    }
547    if (audioPolicyEffects == 0) {
548        *count = 0;
549        return NO_INIT;
550    }
551    return audioPolicyEffects->queryDefaultInputEffects(audioSession, descriptors, count);
552}
553
554bool AudioPolicyService::isOffloadSupported(const audio_offload_info_t& info)
555{
556    if (mAudioPolicyManager == NULL) {
557        ALOGV("mAudioPolicyManager == NULL");
558        return false;
559    }
560
561    return mAudioPolicyManager->isOffloadSupported(info);
562}
563
564status_t AudioPolicyService::listAudioPorts(audio_port_role_t role,
565                                            audio_port_type_t type,
566                                            unsigned int *num_ports,
567                                            struct audio_port *ports,
568                                            unsigned int *generation)
569{
570    Mutex::Autolock _l(mLock);
571    if (mAudioPolicyManager == NULL) {
572        return NO_INIT;
573    }
574
575    return mAudioPolicyManager->listAudioPorts(role, type, num_ports, ports, generation);
576}
577
578status_t AudioPolicyService::getAudioPort(struct audio_port *port)
579{
580    Mutex::Autolock _l(mLock);
581    if (mAudioPolicyManager == NULL) {
582        return NO_INIT;
583    }
584
585    return mAudioPolicyManager->getAudioPort(port);
586}
587
588status_t AudioPolicyService::createAudioPatch(const struct audio_patch *patch,
589        audio_patch_handle_t *handle)
590{
591    Mutex::Autolock _l(mLock);
592    if(!modifyAudioRoutingAllowed()) {
593        return PERMISSION_DENIED;
594    }
595    if (mAudioPolicyManager == NULL) {
596        return NO_INIT;
597    }
598    return mAudioPolicyManager->createAudioPatch(patch, handle,
599                                                  IPCThreadState::self()->getCallingUid());
600}
601
602status_t AudioPolicyService::releaseAudioPatch(audio_patch_handle_t handle)
603{
604    Mutex::Autolock _l(mLock);
605    if(!modifyAudioRoutingAllowed()) {
606        return PERMISSION_DENIED;
607    }
608    if (mAudioPolicyManager == NULL) {
609        return NO_INIT;
610    }
611
612    return mAudioPolicyManager->releaseAudioPatch(handle,
613                                                     IPCThreadState::self()->getCallingUid());
614}
615
616status_t AudioPolicyService::listAudioPatches(unsigned int *num_patches,
617        struct audio_patch *patches,
618        unsigned int *generation)
619{
620    Mutex::Autolock _l(mLock);
621    if (mAudioPolicyManager == NULL) {
622        return NO_INIT;
623    }
624
625    return mAudioPolicyManager->listAudioPatches(num_patches, patches, generation);
626}
627
628status_t AudioPolicyService::setAudioPortConfig(const struct audio_port_config *config)
629{
630    Mutex::Autolock _l(mLock);
631    if(!modifyAudioRoutingAllowed()) {
632        return PERMISSION_DENIED;
633    }
634    if (mAudioPolicyManager == NULL) {
635        return NO_INIT;
636    }
637
638    return mAudioPolicyManager->setAudioPortConfig(config);
639}
640
641status_t AudioPolicyService::acquireSoundTriggerSession(audio_session_t *session,
642                                       audio_io_handle_t *ioHandle,
643                                       audio_devices_t *device)
644{
645    if (mAudioPolicyManager == NULL) {
646        return NO_INIT;
647    }
648
649    return mAudioPolicyManager->acquireSoundTriggerSession(session, ioHandle, device);
650}
651
652status_t AudioPolicyService::releaseSoundTriggerSession(audio_session_t session)
653{
654    if (mAudioPolicyManager == NULL) {
655        return NO_INIT;
656    }
657
658    return mAudioPolicyManager->releaseSoundTriggerSession(session);
659}
660
661status_t AudioPolicyService::registerPolicyMixes(Vector<AudioMix> mixes, bool registration)
662{
663    Mutex::Autolock _l(mLock);
664    if(!modifyAudioRoutingAllowed()) {
665        return PERMISSION_DENIED;
666    }
667    if (mAudioPolicyManager == NULL) {
668        return NO_INIT;
669    }
670    if (registration) {
671        return mAudioPolicyManager->registerPolicyMixes(mixes);
672    } else {
673        return mAudioPolicyManager->unregisterPolicyMixes(mixes);
674    }
675}
676
677status_t AudioPolicyService::startAudioSource(const struct audio_port_config *source,
678                                  const audio_attributes_t *attributes,
679                                  audio_io_handle_t *handle)
680{
681    Mutex::Autolock _l(mLock);
682    if (mAudioPolicyManager == NULL) {
683        return NO_INIT;
684    }
685
686    return mAudioPolicyManager->startAudioSource(source, attributes, handle);
687}
688
689status_t AudioPolicyService::stopAudioSource(audio_io_handle_t handle)
690{
691    Mutex::Autolock _l(mLock);
692    if (mAudioPolicyManager == NULL) {
693        return NO_INIT;
694    }
695
696    return mAudioPolicyManager->stopAudioSource(handle);
697}
698
699}; // namespace android
700