IAudioFlinger.cpp revision 1cda6afaf6207a41303e653a6ecd7909d73186eb
1/*
2**
3** Copyright 2007, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9**     http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#define LOG_TAG "IAudioFlinger"
19//#define LOG_NDEBUG 0
20#include <utils/Log.h>
21
22#include <stdint.h>
23#include <sys/types.h>
24
25#include <binder/Parcel.h>
26
27#include <media/IAudioFlinger.h>
28
29namespace android {
30
31enum {
32    CREATE_TRACK = IBinder::FIRST_CALL_TRANSACTION,
33    OPEN_RECORD,
34    SAMPLE_RATE,
35    RESERVED,   // obsolete, was CHANNEL_COUNT
36    FORMAT,
37    FRAME_COUNT,
38    LATENCY,
39    SET_MASTER_VOLUME,
40    SET_MASTER_MUTE,
41    MASTER_VOLUME,
42    MASTER_MUTE,
43    SET_STREAM_VOLUME,
44    SET_STREAM_MUTE,
45    STREAM_VOLUME,
46    STREAM_MUTE,
47    SET_MODE,
48    SET_MIC_MUTE,
49    GET_MIC_MUTE,
50    SET_PARAMETERS,
51    GET_PARAMETERS,
52    REGISTER_CLIENT,
53    GET_INPUTBUFFERSIZE,
54    OPEN_OUTPUT,
55    OPEN_DUPLICATE_OUTPUT,
56    CLOSE_OUTPUT,
57    SUSPEND_OUTPUT,
58    RESTORE_OUTPUT,
59    OPEN_INPUT,
60    CLOSE_INPUT,
61    INVALIDATE_STREAM,
62    SET_VOICE_VOLUME,
63    GET_RENDER_POSITION,
64    GET_INPUT_FRAMES_LOST,
65    NEW_AUDIO_SESSION_ID,
66    ACQUIRE_AUDIO_SESSION_ID,
67    RELEASE_AUDIO_SESSION_ID,
68    QUERY_NUM_EFFECTS,
69    QUERY_EFFECT,
70    GET_EFFECT_DESCRIPTOR,
71    CREATE_EFFECT,
72    MOVE_EFFECTS,
73    LOAD_HW_MODULE,
74    GET_PRIMARY_OUTPUT_SAMPLING_RATE,
75    GET_PRIMARY_OUTPUT_FRAME_COUNT,
76    SET_LOW_RAM_DEVICE,
77    LIST_AUDIO_PORTS,
78    GET_AUDIO_PORT,
79    CREATE_AUDIO_PATCH,
80    RELEASE_AUDIO_PATCH,
81    LIST_AUDIO_PATCHES,
82    SET_AUDIO_PORT_CONFIG
83};
84
85class BpAudioFlinger : public BpInterface<IAudioFlinger>
86{
87public:
88    BpAudioFlinger(const sp<IBinder>& impl)
89        : BpInterface<IAudioFlinger>(impl)
90    {
91    }
92
93    virtual sp<IAudioTrack> createTrack(
94                                audio_stream_type_t streamType,
95                                uint32_t sampleRate,
96                                audio_format_t format,
97                                audio_channel_mask_t channelMask,
98                                size_t *pFrameCount,
99                                track_flags_t *flags,
100                                const sp<IMemory>& sharedBuffer,
101                                audio_io_handle_t output,
102                                pid_t tid,
103                                int *sessionId,
104                                int clientUid,
105                                status_t *status)
106    {
107        Parcel data, reply;
108        sp<IAudioTrack> track;
109        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
110        data.writeInt32((int32_t) streamType);
111        data.writeInt32(sampleRate);
112        data.writeInt32(format);
113        data.writeInt32(channelMask);
114        size_t frameCount = pFrameCount != NULL ? *pFrameCount : 0;
115        data.writeInt64(frameCount);
116        track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT;
117        data.writeInt32(lFlags);
118        // haveSharedBuffer
119        if (sharedBuffer != 0) {
120            data.writeInt32(true);
121            data.writeStrongBinder(sharedBuffer->asBinder());
122        } else {
123            data.writeInt32(false);
124        }
125        data.writeInt32((int32_t) output);
126        data.writeInt32((int32_t) tid);
127        int lSessionId = AUDIO_SESSION_ALLOCATE;
128        if (sessionId != NULL) {
129            lSessionId = *sessionId;
130        }
131        data.writeInt32(lSessionId);
132        data.writeInt32(clientUid);
133        status_t lStatus = remote()->transact(CREATE_TRACK, data, &reply);
134        if (lStatus != NO_ERROR) {
135            ALOGE("createTrack error: %s", strerror(-lStatus));
136        } else {
137            frameCount = reply.readInt64();
138            if (pFrameCount != NULL) {
139                *pFrameCount = frameCount;
140            }
141            lFlags = reply.readInt32();
142            if (flags != NULL) {
143                *flags = lFlags;
144            }
145            lSessionId = reply.readInt32();
146            if (sessionId != NULL) {
147                *sessionId = lSessionId;
148            }
149            lStatus = reply.readInt32();
150            track = interface_cast<IAudioTrack>(reply.readStrongBinder());
151            if (lStatus == NO_ERROR) {
152                if (track == 0) {
153                    ALOGE("createTrack should have returned an IAudioTrack");
154                    lStatus = UNKNOWN_ERROR;
155                }
156            } else {
157                if (track != 0) {
158                    ALOGE("createTrack returned an IAudioTrack but with status %d", lStatus);
159                    track.clear();
160                }
161            }
162        }
163        if (status != NULL) {
164            *status = lStatus;
165        }
166        return track;
167    }
168
169    virtual sp<IAudioRecord> openRecord(
170                                audio_io_handle_t input,
171                                uint32_t sampleRate,
172                                audio_format_t format,
173                                audio_channel_mask_t channelMask,
174                                size_t *pFrameCount,
175                                track_flags_t *flags,
176                                pid_t tid,
177                                int *sessionId,
178                                sp<IMemory>& cblk,
179                                sp<IMemory>& buffers,
180                                status_t *status)
181    {
182        Parcel data, reply;
183        sp<IAudioRecord> record;
184        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
185        data.writeInt32((int32_t) input);
186        data.writeInt32(sampleRate);
187        data.writeInt32(format);
188        data.writeInt32(channelMask);
189        size_t frameCount = pFrameCount != NULL ? *pFrameCount : 0;
190        data.writeInt64(frameCount);
191        track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT;
192        data.writeInt32(lFlags);
193        data.writeInt32((int32_t) tid);
194        int lSessionId = AUDIO_SESSION_ALLOCATE;
195        if (sessionId != NULL) {
196            lSessionId = *sessionId;
197        }
198        data.writeInt32(lSessionId);
199        cblk.clear();
200        buffers.clear();
201        status_t lStatus = remote()->transact(OPEN_RECORD, data, &reply);
202        if (lStatus != NO_ERROR) {
203            ALOGE("openRecord error: %s", strerror(-lStatus));
204        } else {
205            frameCount = reply.readInt64();
206            if (pFrameCount != NULL) {
207                *pFrameCount = frameCount;
208            }
209            lFlags = reply.readInt32();
210            if (flags != NULL) {
211                *flags = lFlags;
212            }
213            lSessionId = reply.readInt32();
214            if (sessionId != NULL) {
215                *sessionId = lSessionId;
216            }
217            lStatus = reply.readInt32();
218            record = interface_cast<IAudioRecord>(reply.readStrongBinder());
219            cblk = interface_cast<IMemory>(reply.readStrongBinder());
220            if (cblk != 0 && cblk->pointer() == NULL) {
221                cblk.clear();
222            }
223            buffers = interface_cast<IMemory>(reply.readStrongBinder());
224            if (buffers != 0 && buffers->pointer() == NULL) {
225                buffers.clear();
226            }
227            if (lStatus == NO_ERROR) {
228                if (record == 0) {
229                    ALOGE("openRecord should have returned an IAudioRecord");
230                    lStatus = UNKNOWN_ERROR;
231                } else if (cblk == 0) {
232                    ALOGE("openRecord should have returned a cblk");
233                    lStatus = NO_MEMORY;
234                }
235                // buffers is permitted to be 0
236            } else {
237                if (record != 0 || cblk != 0 || buffers != 0) {
238                    ALOGE("openRecord returned an IAudioRecord, cblk, "
239                          "or buffers but with status %d", lStatus);
240                }
241            }
242            if (lStatus != NO_ERROR) {
243                record.clear();
244                cblk.clear();
245                buffers.clear();
246            }
247        }
248        if (status != NULL) {
249            *status = lStatus;
250        }
251        return record;
252    }
253
254    virtual uint32_t sampleRate(audio_io_handle_t output) const
255    {
256        Parcel data, reply;
257        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
258        data.writeInt32((int32_t) output);
259        remote()->transact(SAMPLE_RATE, data, &reply);
260        return reply.readInt32();
261    }
262
263    virtual audio_format_t format(audio_io_handle_t output) const
264    {
265        Parcel data, reply;
266        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
267        data.writeInt32((int32_t) output);
268        remote()->transact(FORMAT, data, &reply);
269        return (audio_format_t) reply.readInt32();
270    }
271
272    virtual size_t frameCount(audio_io_handle_t output) const
273    {
274        Parcel data, reply;
275        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
276        data.writeInt32((int32_t) output);
277        remote()->transact(FRAME_COUNT, data, &reply);
278        return reply.readInt64();
279    }
280
281    virtual uint32_t latency(audio_io_handle_t output) const
282    {
283        Parcel data, reply;
284        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
285        data.writeInt32((int32_t) output);
286        remote()->transact(LATENCY, data, &reply);
287        return reply.readInt32();
288    }
289
290    virtual status_t setMasterVolume(float value)
291    {
292        Parcel data, reply;
293        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
294        data.writeFloat(value);
295        remote()->transact(SET_MASTER_VOLUME, data, &reply);
296        return reply.readInt32();
297    }
298
299    virtual status_t setMasterMute(bool muted)
300    {
301        Parcel data, reply;
302        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
303        data.writeInt32(muted);
304        remote()->transact(SET_MASTER_MUTE, data, &reply);
305        return reply.readInt32();
306    }
307
308    virtual float masterVolume() const
309    {
310        Parcel data, reply;
311        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
312        remote()->transact(MASTER_VOLUME, data, &reply);
313        return reply.readFloat();
314    }
315
316    virtual bool masterMute() const
317    {
318        Parcel data, reply;
319        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
320        remote()->transact(MASTER_MUTE, data, &reply);
321        return reply.readInt32();
322    }
323
324    virtual status_t setStreamVolume(audio_stream_type_t stream, float value,
325            audio_io_handle_t output)
326    {
327        Parcel data, reply;
328        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
329        data.writeInt32((int32_t) stream);
330        data.writeFloat(value);
331        data.writeInt32((int32_t) output);
332        remote()->transact(SET_STREAM_VOLUME, data, &reply);
333        return reply.readInt32();
334    }
335
336    virtual status_t setStreamMute(audio_stream_type_t stream, bool muted)
337    {
338        Parcel data, reply;
339        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
340        data.writeInt32((int32_t) stream);
341        data.writeInt32(muted);
342        remote()->transact(SET_STREAM_MUTE, data, &reply);
343        return reply.readInt32();
344    }
345
346    virtual float streamVolume(audio_stream_type_t stream, audio_io_handle_t output) const
347    {
348        Parcel data, reply;
349        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
350        data.writeInt32((int32_t) stream);
351        data.writeInt32((int32_t) output);
352        remote()->transact(STREAM_VOLUME, data, &reply);
353        return reply.readFloat();
354    }
355
356    virtual bool streamMute(audio_stream_type_t stream) const
357    {
358        Parcel data, reply;
359        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
360        data.writeInt32((int32_t) stream);
361        remote()->transact(STREAM_MUTE, data, &reply);
362        return reply.readInt32();
363    }
364
365    virtual status_t setMode(audio_mode_t mode)
366    {
367        Parcel data, reply;
368        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
369        data.writeInt32(mode);
370        remote()->transact(SET_MODE, data, &reply);
371        return reply.readInt32();
372    }
373
374    virtual status_t setMicMute(bool state)
375    {
376        Parcel data, reply;
377        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
378        data.writeInt32(state);
379        remote()->transact(SET_MIC_MUTE, data, &reply);
380        return reply.readInt32();
381    }
382
383    virtual bool getMicMute() const
384    {
385        Parcel data, reply;
386        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
387        remote()->transact(GET_MIC_MUTE, data, &reply);
388        return reply.readInt32();
389    }
390
391    virtual status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
392    {
393        Parcel data, reply;
394        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
395        data.writeInt32((int32_t) ioHandle);
396        data.writeString8(keyValuePairs);
397        remote()->transact(SET_PARAMETERS, data, &reply);
398        return reply.readInt32();
399    }
400
401    virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) const
402    {
403        Parcel data, reply;
404        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
405        data.writeInt32((int32_t) ioHandle);
406        data.writeString8(keys);
407        remote()->transact(GET_PARAMETERS, data, &reply);
408        return reply.readString8();
409    }
410
411    virtual void registerClient(const sp<IAudioFlingerClient>& client)
412    {
413        Parcel data, reply;
414        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
415        data.writeStrongBinder(client->asBinder());
416        remote()->transact(REGISTER_CLIENT, data, &reply);
417    }
418
419    virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
420            audio_channel_mask_t channelMask) const
421    {
422        Parcel data, reply;
423        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
424        data.writeInt32(sampleRate);
425        data.writeInt32(format);
426        data.writeInt32(channelMask);
427        remote()->transact(GET_INPUTBUFFERSIZE, data, &reply);
428        return reply.readInt64();
429    }
430
431    virtual audio_io_handle_t openOutput(audio_module_handle_t module,
432                                         audio_devices_t *pDevices,
433                                         uint32_t *pSamplingRate,
434                                         audio_format_t *pFormat,
435                                         audio_channel_mask_t *pChannelMask,
436                                         uint32_t *pLatencyMs,
437                                         audio_output_flags_t flags,
438                                         const audio_offload_info_t *offloadInfo)
439    {
440        Parcel data, reply;
441        audio_devices_t devices = pDevices != NULL ? *pDevices : AUDIO_DEVICE_NONE;
442        uint32_t samplingRate = pSamplingRate != NULL ? *pSamplingRate : 0;
443        audio_format_t format = pFormat != NULL ? *pFormat : AUDIO_FORMAT_DEFAULT;
444        audio_channel_mask_t channelMask = pChannelMask != NULL ?
445                *pChannelMask : (audio_channel_mask_t)0;
446        uint32_t latency = pLatencyMs != NULL ? *pLatencyMs : 0;
447        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
448        data.writeInt32(module);
449        data.writeInt32(devices);
450        data.writeInt32(samplingRate);
451        data.writeInt32(format);
452        data.writeInt32(channelMask);
453        data.writeInt32(latency);
454        data.writeInt32((int32_t) flags);
455        // hasOffloadInfo
456        if (offloadInfo == NULL) {
457            data.writeInt32(0);
458        } else {
459            data.writeInt32(1);
460            data.write(offloadInfo, sizeof(audio_offload_info_t));
461        }
462        remote()->transact(OPEN_OUTPUT, data, &reply);
463        audio_io_handle_t output = (audio_io_handle_t) reply.readInt32();
464        ALOGV("openOutput() returned output, %d", output);
465        devices = (audio_devices_t)reply.readInt32();
466        if (pDevices != NULL) {
467            *pDevices = devices;
468        }
469        samplingRate = reply.readInt32();
470        if (pSamplingRate != NULL) {
471            *pSamplingRate = samplingRate;
472        }
473        format = (audio_format_t) reply.readInt32();
474        if (pFormat != NULL) {
475            *pFormat = format;
476        }
477        channelMask = (audio_channel_mask_t)reply.readInt32();
478        if (pChannelMask != NULL) {
479            *pChannelMask = channelMask;
480        }
481        latency = reply.readInt32();
482        if (pLatencyMs != NULL) {
483            *pLatencyMs = latency;
484        }
485        return output;
486    }
487
488    virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
489            audio_io_handle_t output2)
490    {
491        Parcel data, reply;
492        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
493        data.writeInt32((int32_t) output1);
494        data.writeInt32((int32_t) output2);
495        remote()->transact(OPEN_DUPLICATE_OUTPUT, data, &reply);
496        return (audio_io_handle_t) reply.readInt32();
497    }
498
499    virtual status_t closeOutput(audio_io_handle_t output)
500    {
501        Parcel data, reply;
502        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
503        data.writeInt32((int32_t) output);
504        remote()->transact(CLOSE_OUTPUT, data, &reply);
505        return reply.readInt32();
506    }
507
508    virtual status_t suspendOutput(audio_io_handle_t output)
509    {
510        Parcel data, reply;
511        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
512        data.writeInt32((int32_t) output);
513        remote()->transact(SUSPEND_OUTPUT, data, &reply);
514        return reply.readInt32();
515    }
516
517    virtual status_t restoreOutput(audio_io_handle_t output)
518    {
519        Parcel data, reply;
520        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
521        data.writeInt32((int32_t) output);
522        remote()->transact(RESTORE_OUTPUT, data, &reply);
523        return reply.readInt32();
524    }
525
526    virtual audio_io_handle_t openInput(audio_module_handle_t module,
527                                        audio_devices_t *pDevices,
528                                        uint32_t *pSamplingRate,
529                                        audio_format_t *pFormat,
530                                        audio_channel_mask_t *pChannelMask)
531    {
532        Parcel data, reply;
533        audio_devices_t devices = pDevices != NULL ? *pDevices : AUDIO_DEVICE_NONE;
534        uint32_t samplingRate = pSamplingRate != NULL ? *pSamplingRate : 0;
535        audio_format_t format = pFormat != NULL ? *pFormat : AUDIO_FORMAT_DEFAULT;
536        audio_channel_mask_t channelMask = pChannelMask != NULL ?
537                *pChannelMask : (audio_channel_mask_t)0;
538
539        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
540        data.writeInt32(module);
541        data.writeInt32(devices);
542        data.writeInt32(samplingRate);
543        data.writeInt32(format);
544        data.writeInt32(channelMask);
545        remote()->transact(OPEN_INPUT, data, &reply);
546        audio_io_handle_t input = (audio_io_handle_t) reply.readInt32();
547        devices = (audio_devices_t)reply.readInt32();
548        if (pDevices != NULL) {
549            *pDevices = devices;
550        }
551        samplingRate = reply.readInt32();
552        if (pSamplingRate != NULL) {
553            *pSamplingRate = samplingRate;
554        }
555        format = (audio_format_t) reply.readInt32();
556        if (pFormat != NULL) {
557            *pFormat = format;
558        }
559        channelMask = (audio_channel_mask_t)reply.readInt32();
560        if (pChannelMask != NULL) {
561            *pChannelMask = channelMask;
562        }
563        return input;
564    }
565
566    virtual status_t closeInput(int input)
567    {
568        Parcel data, reply;
569        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
570        data.writeInt32(input);
571        remote()->transact(CLOSE_INPUT, data, &reply);
572        return reply.readInt32();
573    }
574
575    virtual status_t invalidateStream(audio_stream_type_t stream)
576    {
577        Parcel data, reply;
578        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
579        data.writeInt32((int32_t) stream);
580        remote()->transact(INVALIDATE_STREAM, data, &reply);
581        return reply.readInt32();
582    }
583
584    virtual status_t setVoiceVolume(float volume)
585    {
586        Parcel data, reply;
587        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
588        data.writeFloat(volume);
589        remote()->transact(SET_VOICE_VOLUME, data, &reply);
590        return reply.readInt32();
591    }
592
593    virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
594            audio_io_handle_t output) const
595    {
596        Parcel data, reply;
597        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
598        data.writeInt32((int32_t) output);
599        remote()->transact(GET_RENDER_POSITION, data, &reply);
600        status_t status = reply.readInt32();
601        if (status == NO_ERROR) {
602            uint32_t tmp = reply.readInt32();
603            if (halFrames != NULL) {
604                *halFrames = tmp;
605            }
606            tmp = reply.readInt32();
607            if (dspFrames != NULL) {
608                *dspFrames = tmp;
609            }
610        }
611        return status;
612    }
613
614    virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const
615    {
616        Parcel data, reply;
617        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
618        data.writeInt32((int32_t) ioHandle);
619        status_t status = remote()->transact(GET_INPUT_FRAMES_LOST, data, &reply);
620        if (status != NO_ERROR) {
621            return 0;
622        }
623        return (uint32_t) reply.readInt32();
624    }
625
626    virtual int newAudioSessionId()
627    {
628        Parcel data, reply;
629        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
630        status_t status = remote()->transact(NEW_AUDIO_SESSION_ID, data, &reply);
631        int id = AUDIO_SESSION_ALLOCATE;
632        if (status == NO_ERROR) {
633            id = reply.readInt32();
634        }
635        return id;
636    }
637
638    virtual void acquireAudioSessionId(int audioSession, int pid)
639    {
640        Parcel data, reply;
641        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
642        data.writeInt32(audioSession);
643        data.writeInt32(pid);
644        remote()->transact(ACQUIRE_AUDIO_SESSION_ID, data, &reply);
645    }
646
647    virtual void releaseAudioSessionId(int audioSession, int pid)
648    {
649        Parcel data, reply;
650        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
651        data.writeInt32(audioSession);
652        data.writeInt32(pid);
653        remote()->transact(RELEASE_AUDIO_SESSION_ID, data, &reply);
654    }
655
656    virtual status_t queryNumberEffects(uint32_t *numEffects) const
657    {
658        Parcel data, reply;
659        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
660        status_t status = remote()->transact(QUERY_NUM_EFFECTS, data, &reply);
661        if (status != NO_ERROR) {
662            return status;
663        }
664        status = reply.readInt32();
665        if (status != NO_ERROR) {
666            return status;
667        }
668        if (numEffects != NULL) {
669            *numEffects = (uint32_t)reply.readInt32();
670        }
671        return NO_ERROR;
672    }
673
674    virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) const
675    {
676        if (pDescriptor == NULL) {
677            return BAD_VALUE;
678        }
679        Parcel data, reply;
680        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
681        data.writeInt32(index);
682        status_t status = remote()->transact(QUERY_EFFECT, data, &reply);
683        if (status != NO_ERROR) {
684            return status;
685        }
686        status = reply.readInt32();
687        if (status != NO_ERROR) {
688            return status;
689        }
690        reply.read(pDescriptor, sizeof(effect_descriptor_t));
691        return NO_ERROR;
692    }
693
694    virtual status_t getEffectDescriptor(const effect_uuid_t *pUuid,
695            effect_descriptor_t *pDescriptor) const
696    {
697        if (pUuid == NULL || pDescriptor == NULL) {
698            return BAD_VALUE;
699        }
700        Parcel data, reply;
701        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
702        data.write(pUuid, sizeof(effect_uuid_t));
703        status_t status = remote()->transact(GET_EFFECT_DESCRIPTOR, data, &reply);
704        if (status != NO_ERROR) {
705            return status;
706        }
707        status = reply.readInt32();
708        if (status != NO_ERROR) {
709            return status;
710        }
711        reply.read(pDescriptor, sizeof(effect_descriptor_t));
712        return NO_ERROR;
713    }
714
715    virtual sp<IEffect> createEffect(
716                                    effect_descriptor_t *pDesc,
717                                    const sp<IEffectClient>& client,
718                                    int32_t priority,
719                                    audio_io_handle_t output,
720                                    int sessionId,
721                                    status_t *status,
722                                    int *id,
723                                    int *enabled)
724    {
725        Parcel data, reply;
726        sp<IEffect> effect;
727
728        if (pDesc == NULL) {
729            return effect;
730            if (status != NULL) {
731                *status = BAD_VALUE;
732            }
733        }
734
735        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
736        data.write(pDesc, sizeof(effect_descriptor_t));
737        data.writeStrongBinder(client->asBinder());
738        data.writeInt32(priority);
739        data.writeInt32((int32_t) output);
740        data.writeInt32(sessionId);
741
742        status_t lStatus = remote()->transact(CREATE_EFFECT, data, &reply);
743        if (lStatus != NO_ERROR) {
744            ALOGE("createEffect error: %s", strerror(-lStatus));
745        } else {
746            lStatus = reply.readInt32();
747            int tmp = reply.readInt32();
748            if (id != NULL) {
749                *id = tmp;
750            }
751            tmp = reply.readInt32();
752            if (enabled != NULL) {
753                *enabled = tmp;
754            }
755            effect = interface_cast<IEffect>(reply.readStrongBinder());
756            reply.read(pDesc, sizeof(effect_descriptor_t));
757        }
758        if (status != NULL) {
759            *status = lStatus;
760        }
761
762        return effect;
763    }
764
765    virtual status_t moveEffects(int session, audio_io_handle_t srcOutput,
766            audio_io_handle_t dstOutput)
767    {
768        Parcel data, reply;
769        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
770        data.writeInt32(session);
771        data.writeInt32((int32_t) srcOutput);
772        data.writeInt32((int32_t) dstOutput);
773        remote()->transact(MOVE_EFFECTS, data, &reply);
774        return reply.readInt32();
775    }
776
777    virtual audio_module_handle_t loadHwModule(const char *name)
778    {
779        Parcel data, reply;
780        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
781        data.writeCString(name);
782        remote()->transact(LOAD_HW_MODULE, data, &reply);
783        return (audio_module_handle_t) reply.readInt32();
784    }
785
786    virtual uint32_t getPrimaryOutputSamplingRate()
787    {
788        Parcel data, reply;
789        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
790        remote()->transact(GET_PRIMARY_OUTPUT_SAMPLING_RATE, data, &reply);
791        return reply.readInt32();
792    }
793
794    virtual size_t getPrimaryOutputFrameCount()
795    {
796        Parcel data, reply;
797        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
798        remote()->transact(GET_PRIMARY_OUTPUT_FRAME_COUNT, data, &reply);
799        return reply.readInt64();
800    }
801
802    virtual status_t setLowRamDevice(bool isLowRamDevice)
803    {
804        Parcel data, reply;
805        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
806        data.writeInt32((int) isLowRamDevice);
807        remote()->transact(SET_LOW_RAM_DEVICE, data, &reply);
808        return reply.readInt32();
809    }
810    virtual status_t listAudioPorts(unsigned int *num_ports,
811                                    struct audio_port *ports)
812    {
813        if (num_ports == NULL || *num_ports == 0 || ports == NULL) {
814            return BAD_VALUE;
815        }
816        Parcel data, reply;
817        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
818        data.writeInt32(*num_ports);
819        status_t status = remote()->transact(LIST_AUDIO_PORTS, data, &reply);
820        if (status != NO_ERROR ||
821                (status = (status_t)reply.readInt32()) != NO_ERROR) {
822            return status;
823        }
824        *num_ports = (unsigned int)reply.readInt32();
825        reply.read(ports, *num_ports * sizeof(struct audio_port));
826        return status;
827    }
828    virtual status_t getAudioPort(struct audio_port *port)
829    {
830        if (port == NULL) {
831            return BAD_VALUE;
832        }
833        Parcel data, reply;
834        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
835        data.write(port, sizeof(struct audio_port));
836        status_t status = remote()->transact(GET_AUDIO_PORT, data, &reply);
837        if (status != NO_ERROR ||
838                (status = (status_t)reply.readInt32()) != NO_ERROR) {
839            return status;
840        }
841        reply.read(port, sizeof(struct audio_port));
842        return status;
843    }
844    virtual status_t createAudioPatch(const struct audio_patch *patch,
845                                       audio_patch_handle_t *handle)
846    {
847        if (patch == NULL || handle == NULL) {
848            return BAD_VALUE;
849        }
850        Parcel data, reply;
851        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
852        data.write(patch, sizeof(struct audio_patch));
853        data.write(handle, sizeof(audio_patch_handle_t));
854        status_t status = remote()->transact(CREATE_AUDIO_PATCH, data, &reply);
855        if (status != NO_ERROR ||
856                (status = (status_t)reply.readInt32()) != NO_ERROR) {
857            return status;
858        }
859        reply.read(handle, sizeof(audio_patch_handle_t));
860        return status;
861    }
862    virtual status_t releaseAudioPatch(audio_patch_handle_t handle)
863    {
864        Parcel data, reply;
865        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
866        data.write(&handle, sizeof(audio_patch_handle_t));
867        status_t status = remote()->transact(RELEASE_AUDIO_PATCH, data, &reply);
868        if (status != NO_ERROR) {
869            status = (status_t)reply.readInt32();
870        }
871        return status;
872    }
873    virtual status_t listAudioPatches(unsigned int *num_patches,
874                                      struct audio_patch *patches)
875    {
876        if (num_patches == NULL || *num_patches == 0 || patches == NULL) {
877            return BAD_VALUE;
878        }
879        Parcel data, reply;
880        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
881        data.writeInt32(*num_patches);
882        status_t status = remote()->transact(LIST_AUDIO_PATCHES, data, &reply);
883        if (status != NO_ERROR ||
884                (status = (status_t)reply.readInt32()) != NO_ERROR) {
885            return status;
886        }
887        *num_patches = (unsigned int)reply.readInt32();
888        reply.read(patches, *num_patches * sizeof(struct audio_patch));
889        return status;
890    }
891    virtual status_t setAudioPortConfig(const struct audio_port_config *config)
892    {
893        if (config == NULL) {
894            return BAD_VALUE;
895        }
896        Parcel data, reply;
897        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
898        data.write(config, sizeof(struct audio_port_config));
899        status_t status = remote()->transact(SET_AUDIO_PORT_CONFIG, data, &reply);
900        if (status != NO_ERROR) {
901            status = (status_t)reply.readInt32();
902        }
903        return status;
904    }
905};
906
907IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
908
909// ----------------------------------------------------------------------
910
911status_t BnAudioFlinger::onTransact(
912    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
913{
914    switch (code) {
915        case CREATE_TRACK: {
916            CHECK_INTERFACE(IAudioFlinger, data, reply);
917            int streamType = data.readInt32();
918            uint32_t sampleRate = data.readInt32();
919            audio_format_t format = (audio_format_t) data.readInt32();
920            audio_channel_mask_t channelMask = data.readInt32();
921            size_t frameCount = data.readInt64();
922            track_flags_t flags = (track_flags_t) data.readInt32();
923            bool haveSharedBuffer = data.readInt32() != 0;
924            sp<IMemory> buffer;
925            if (haveSharedBuffer) {
926                buffer = interface_cast<IMemory>(data.readStrongBinder());
927            }
928            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
929            pid_t tid = (pid_t) data.readInt32();
930            int sessionId = data.readInt32();
931            int clientUid = data.readInt32();
932            status_t status;
933            sp<IAudioTrack> track;
934            if ((haveSharedBuffer && (buffer == 0)) ||
935                    ((buffer != 0) && (buffer->pointer() == NULL))) {
936                ALOGW("CREATE_TRACK: cannot retrieve shared memory");
937                status = DEAD_OBJECT;
938            } else {
939                track = createTrack(
940                        (audio_stream_type_t) streamType, sampleRate, format,
941                        channelMask, &frameCount, &flags, buffer, output, tid,
942                        &sessionId, clientUid, &status);
943                LOG_ALWAYS_FATAL_IF((track != 0) != (status == NO_ERROR));
944            }
945            reply->writeInt64(frameCount);
946            reply->writeInt32(flags);
947            reply->writeInt32(sessionId);
948            reply->writeInt32(status);
949            reply->writeStrongBinder(track->asBinder());
950            return NO_ERROR;
951        } break;
952        case OPEN_RECORD: {
953            CHECK_INTERFACE(IAudioFlinger, data, reply);
954            audio_io_handle_t input = (audio_io_handle_t) data.readInt32();
955            uint32_t sampleRate = data.readInt32();
956            audio_format_t format = (audio_format_t) data.readInt32();
957            audio_channel_mask_t channelMask = data.readInt32();
958            size_t frameCount = data.readInt64();
959            track_flags_t flags = (track_flags_t) data.readInt32();
960            pid_t tid = (pid_t) data.readInt32();
961            int sessionId = data.readInt32();
962            sp<IMemory> cblk;
963            sp<IMemory> buffers;
964            status_t status;
965            sp<IAudioRecord> record = openRecord(input,
966                    sampleRate, format, channelMask, &frameCount, &flags, tid, &sessionId,
967                    cblk, buffers, &status);
968            LOG_ALWAYS_FATAL_IF((record != 0) != (status == NO_ERROR));
969            reply->writeInt64(frameCount);
970            reply->writeInt32(flags);
971            reply->writeInt32(sessionId);
972            reply->writeInt32(status);
973            reply->writeStrongBinder(record->asBinder());
974            reply->writeStrongBinder(cblk->asBinder());
975            reply->writeStrongBinder(buffers->asBinder());
976            return NO_ERROR;
977        } break;
978        case SAMPLE_RATE: {
979            CHECK_INTERFACE(IAudioFlinger, data, reply);
980            reply->writeInt32( sampleRate((audio_io_handle_t) data.readInt32()) );
981            return NO_ERROR;
982        } break;
983        case FORMAT: {
984            CHECK_INTERFACE(IAudioFlinger, data, reply);
985            reply->writeInt32( format((audio_io_handle_t) data.readInt32()) );
986            return NO_ERROR;
987        } break;
988        case FRAME_COUNT: {
989            CHECK_INTERFACE(IAudioFlinger, data, reply);
990            reply->writeInt64( frameCount((audio_io_handle_t) data.readInt32()) );
991            return NO_ERROR;
992        } break;
993        case LATENCY: {
994            CHECK_INTERFACE(IAudioFlinger, data, reply);
995            reply->writeInt32( latency((audio_io_handle_t) data.readInt32()) );
996            return NO_ERROR;
997        } break;
998        case SET_MASTER_VOLUME: {
999            CHECK_INTERFACE(IAudioFlinger, data, reply);
1000            reply->writeInt32( setMasterVolume(data.readFloat()) );
1001            return NO_ERROR;
1002        } break;
1003        case SET_MASTER_MUTE: {
1004            CHECK_INTERFACE(IAudioFlinger, data, reply);
1005            reply->writeInt32( setMasterMute(data.readInt32()) );
1006            return NO_ERROR;
1007        } break;
1008        case MASTER_VOLUME: {
1009            CHECK_INTERFACE(IAudioFlinger, data, reply);
1010            reply->writeFloat( masterVolume() );
1011            return NO_ERROR;
1012        } break;
1013        case MASTER_MUTE: {
1014            CHECK_INTERFACE(IAudioFlinger, data, reply);
1015            reply->writeInt32( masterMute() );
1016            return NO_ERROR;
1017        } break;
1018        case SET_STREAM_VOLUME: {
1019            CHECK_INTERFACE(IAudioFlinger, data, reply);
1020            int stream = data.readInt32();
1021            float volume = data.readFloat();
1022            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
1023            reply->writeInt32( setStreamVolume((audio_stream_type_t) stream, volume, output) );
1024            return NO_ERROR;
1025        } break;
1026        case SET_STREAM_MUTE: {
1027            CHECK_INTERFACE(IAudioFlinger, data, reply);
1028            int stream = data.readInt32();
1029            reply->writeInt32( setStreamMute((audio_stream_type_t) stream, data.readInt32()) );
1030            return NO_ERROR;
1031        } break;
1032        case STREAM_VOLUME: {
1033            CHECK_INTERFACE(IAudioFlinger, data, reply);
1034            int stream = data.readInt32();
1035            int output = data.readInt32();
1036            reply->writeFloat( streamVolume((audio_stream_type_t) stream, output) );
1037            return NO_ERROR;
1038        } break;
1039        case STREAM_MUTE: {
1040            CHECK_INTERFACE(IAudioFlinger, data, reply);
1041            int stream = data.readInt32();
1042            reply->writeInt32( streamMute((audio_stream_type_t) stream) );
1043            return NO_ERROR;
1044        } break;
1045        case SET_MODE: {
1046            CHECK_INTERFACE(IAudioFlinger, data, reply);
1047            audio_mode_t mode = (audio_mode_t) data.readInt32();
1048            reply->writeInt32( setMode(mode) );
1049            return NO_ERROR;
1050        } break;
1051        case SET_MIC_MUTE: {
1052            CHECK_INTERFACE(IAudioFlinger, data, reply);
1053            int state = data.readInt32();
1054            reply->writeInt32( setMicMute(state) );
1055            return NO_ERROR;
1056        } break;
1057        case GET_MIC_MUTE: {
1058            CHECK_INTERFACE(IAudioFlinger, data, reply);
1059            reply->writeInt32( getMicMute() );
1060            return NO_ERROR;
1061        } break;
1062        case SET_PARAMETERS: {
1063            CHECK_INTERFACE(IAudioFlinger, data, reply);
1064            audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32();
1065            String8 keyValuePairs(data.readString8());
1066            reply->writeInt32(setParameters(ioHandle, keyValuePairs));
1067            return NO_ERROR;
1068        } break;
1069        case GET_PARAMETERS: {
1070            CHECK_INTERFACE(IAudioFlinger, data, reply);
1071            audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32();
1072            String8 keys(data.readString8());
1073            reply->writeString8(getParameters(ioHandle, keys));
1074            return NO_ERROR;
1075        } break;
1076
1077        case REGISTER_CLIENT: {
1078            CHECK_INTERFACE(IAudioFlinger, data, reply);
1079            sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient>(
1080                    data.readStrongBinder());
1081            registerClient(client);
1082            return NO_ERROR;
1083        } break;
1084        case GET_INPUTBUFFERSIZE: {
1085            CHECK_INTERFACE(IAudioFlinger, data, reply);
1086            uint32_t sampleRate = data.readInt32();
1087            audio_format_t format = (audio_format_t) data.readInt32();
1088            audio_channel_mask_t channelMask = data.readInt32();
1089            reply->writeInt64( getInputBufferSize(sampleRate, format, channelMask) );
1090            return NO_ERROR;
1091        } break;
1092        case OPEN_OUTPUT: {
1093            CHECK_INTERFACE(IAudioFlinger, data, reply);
1094            audio_module_handle_t module = (audio_module_handle_t)data.readInt32();
1095            audio_devices_t devices = (audio_devices_t)data.readInt32();
1096            uint32_t samplingRate = data.readInt32();
1097            audio_format_t format = (audio_format_t) data.readInt32();
1098            audio_channel_mask_t channelMask = (audio_channel_mask_t)data.readInt32();
1099            uint32_t latency = data.readInt32();
1100            audio_output_flags_t flags = (audio_output_flags_t) data.readInt32();
1101            bool hasOffloadInfo = data.readInt32() != 0;
1102            audio_offload_info_t offloadInfo;
1103            if (hasOffloadInfo) {
1104                data.read(&offloadInfo, sizeof(audio_offload_info_t));
1105            }
1106            audio_io_handle_t output = openOutput(module,
1107                                                 &devices,
1108                                                 &samplingRate,
1109                                                 &format,
1110                                                 &channelMask,
1111                                                 &latency,
1112                                                 flags,
1113                                                 hasOffloadInfo ? &offloadInfo : NULL);
1114            ALOGV("OPEN_OUTPUT output, %d", output);
1115            reply->writeInt32((int32_t) output);
1116            reply->writeInt32(devices);
1117            reply->writeInt32(samplingRate);
1118            reply->writeInt32(format);
1119            reply->writeInt32(channelMask);
1120            reply->writeInt32(latency);
1121            return NO_ERROR;
1122        } break;
1123        case OPEN_DUPLICATE_OUTPUT: {
1124            CHECK_INTERFACE(IAudioFlinger, data, reply);
1125            audio_io_handle_t output1 = (audio_io_handle_t) data.readInt32();
1126            audio_io_handle_t output2 = (audio_io_handle_t) data.readInt32();
1127            reply->writeInt32((int32_t) openDuplicateOutput(output1, output2));
1128            return NO_ERROR;
1129        } break;
1130        case CLOSE_OUTPUT: {
1131            CHECK_INTERFACE(IAudioFlinger, data, reply);
1132            reply->writeInt32(closeOutput((audio_io_handle_t) data.readInt32()));
1133            return NO_ERROR;
1134        } break;
1135        case SUSPEND_OUTPUT: {
1136            CHECK_INTERFACE(IAudioFlinger, data, reply);
1137            reply->writeInt32(suspendOutput((audio_io_handle_t) data.readInt32()));
1138            return NO_ERROR;
1139        } break;
1140        case RESTORE_OUTPUT: {
1141            CHECK_INTERFACE(IAudioFlinger, data, reply);
1142            reply->writeInt32(restoreOutput((audio_io_handle_t) data.readInt32()));
1143            return NO_ERROR;
1144        } break;
1145        case OPEN_INPUT: {
1146            CHECK_INTERFACE(IAudioFlinger, data, reply);
1147            audio_module_handle_t module = (audio_module_handle_t)data.readInt32();
1148            audio_devices_t devices = (audio_devices_t)data.readInt32();
1149            uint32_t samplingRate = data.readInt32();
1150            audio_format_t format = (audio_format_t) data.readInt32();
1151            audio_channel_mask_t channelMask = (audio_channel_mask_t)data.readInt32();
1152
1153            audio_io_handle_t input = openInput(module,
1154                                             &devices,
1155                                             &samplingRate,
1156                                             &format,
1157                                             &channelMask);
1158            reply->writeInt32((int32_t) input);
1159            reply->writeInt32(devices);
1160            reply->writeInt32(samplingRate);
1161            reply->writeInt32(format);
1162            reply->writeInt32(channelMask);
1163            return NO_ERROR;
1164        } break;
1165        case CLOSE_INPUT: {
1166            CHECK_INTERFACE(IAudioFlinger, data, reply);
1167            reply->writeInt32(closeInput((audio_io_handle_t) data.readInt32()));
1168            return NO_ERROR;
1169        } break;
1170        case INVALIDATE_STREAM: {
1171            CHECK_INTERFACE(IAudioFlinger, data, reply);
1172            audio_stream_type_t stream = (audio_stream_type_t) data.readInt32();
1173            reply->writeInt32(invalidateStream(stream));
1174            return NO_ERROR;
1175        } break;
1176        case SET_VOICE_VOLUME: {
1177            CHECK_INTERFACE(IAudioFlinger, data, reply);
1178            float volume = data.readFloat();
1179            reply->writeInt32( setVoiceVolume(volume) );
1180            return NO_ERROR;
1181        } break;
1182        case GET_RENDER_POSITION: {
1183            CHECK_INTERFACE(IAudioFlinger, data, reply);
1184            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
1185            uint32_t halFrames;
1186            uint32_t dspFrames;
1187            status_t status = getRenderPosition(&halFrames, &dspFrames, output);
1188            reply->writeInt32(status);
1189            if (status == NO_ERROR) {
1190                reply->writeInt32(halFrames);
1191                reply->writeInt32(dspFrames);
1192            }
1193            return NO_ERROR;
1194        }
1195        case GET_INPUT_FRAMES_LOST: {
1196            CHECK_INTERFACE(IAudioFlinger, data, reply);
1197            audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32();
1198            reply->writeInt32((int32_t) getInputFramesLost(ioHandle));
1199            return NO_ERROR;
1200        } break;
1201        case NEW_AUDIO_SESSION_ID: {
1202            CHECK_INTERFACE(IAudioFlinger, data, reply);
1203            reply->writeInt32(newAudioSessionId());
1204            return NO_ERROR;
1205        } break;
1206        case ACQUIRE_AUDIO_SESSION_ID: {
1207            CHECK_INTERFACE(IAudioFlinger, data, reply);
1208            int audioSession = data.readInt32();
1209            int pid = data.readInt32();
1210            acquireAudioSessionId(audioSession, pid);
1211            return NO_ERROR;
1212        } break;
1213        case RELEASE_AUDIO_SESSION_ID: {
1214            CHECK_INTERFACE(IAudioFlinger, data, reply);
1215            int audioSession = data.readInt32();
1216            int pid = data.readInt32();
1217            releaseAudioSessionId(audioSession, pid);
1218            return NO_ERROR;
1219        } break;
1220        case QUERY_NUM_EFFECTS: {
1221            CHECK_INTERFACE(IAudioFlinger, data, reply);
1222            uint32_t numEffects;
1223            status_t status = queryNumberEffects(&numEffects);
1224            reply->writeInt32(status);
1225            if (status == NO_ERROR) {
1226                reply->writeInt32((int32_t)numEffects);
1227            }
1228            return NO_ERROR;
1229        }
1230        case QUERY_EFFECT: {
1231            CHECK_INTERFACE(IAudioFlinger, data, reply);
1232            effect_descriptor_t desc;
1233            status_t status = queryEffect(data.readInt32(), &desc);
1234            reply->writeInt32(status);
1235            if (status == NO_ERROR) {
1236                reply->write(&desc, sizeof(effect_descriptor_t));
1237            }
1238            return NO_ERROR;
1239        }
1240        case GET_EFFECT_DESCRIPTOR: {
1241            CHECK_INTERFACE(IAudioFlinger, data, reply);
1242            effect_uuid_t uuid;
1243            data.read(&uuid, sizeof(effect_uuid_t));
1244            effect_descriptor_t desc;
1245            status_t status = getEffectDescriptor(&uuid, &desc);
1246            reply->writeInt32(status);
1247            if (status == NO_ERROR) {
1248                reply->write(&desc, sizeof(effect_descriptor_t));
1249            }
1250            return NO_ERROR;
1251        }
1252        case CREATE_EFFECT: {
1253            CHECK_INTERFACE(IAudioFlinger, data, reply);
1254            effect_descriptor_t desc;
1255            data.read(&desc, sizeof(effect_descriptor_t));
1256            sp<IEffectClient> client = interface_cast<IEffectClient>(data.readStrongBinder());
1257            int32_t priority = data.readInt32();
1258            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
1259            int sessionId = data.readInt32();
1260            status_t status;
1261            int id;
1262            int enabled;
1263
1264            sp<IEffect> effect = createEffect(&desc, client, priority, output, sessionId,
1265                    &status, &id, &enabled);
1266            reply->writeInt32(status);
1267            reply->writeInt32(id);
1268            reply->writeInt32(enabled);
1269            reply->writeStrongBinder(effect->asBinder());
1270            reply->write(&desc, sizeof(effect_descriptor_t));
1271            return NO_ERROR;
1272        } break;
1273        case MOVE_EFFECTS: {
1274            CHECK_INTERFACE(IAudioFlinger, data, reply);
1275            int session = data.readInt32();
1276            audio_io_handle_t srcOutput = (audio_io_handle_t) data.readInt32();
1277            audio_io_handle_t dstOutput = (audio_io_handle_t) data.readInt32();
1278            reply->writeInt32(moveEffects(session, srcOutput, dstOutput));
1279            return NO_ERROR;
1280        } break;
1281        case LOAD_HW_MODULE: {
1282            CHECK_INTERFACE(IAudioFlinger, data, reply);
1283            reply->writeInt32(loadHwModule(data.readCString()));
1284            return NO_ERROR;
1285        } break;
1286        case GET_PRIMARY_OUTPUT_SAMPLING_RATE: {
1287            CHECK_INTERFACE(IAudioFlinger, data, reply);
1288            reply->writeInt32(getPrimaryOutputSamplingRate());
1289            return NO_ERROR;
1290        } break;
1291        case GET_PRIMARY_OUTPUT_FRAME_COUNT: {
1292            CHECK_INTERFACE(IAudioFlinger, data, reply);
1293            reply->writeInt64(getPrimaryOutputFrameCount());
1294            return NO_ERROR;
1295        } break;
1296        case SET_LOW_RAM_DEVICE: {
1297            CHECK_INTERFACE(IAudioFlinger, data, reply);
1298            bool isLowRamDevice = data.readInt32() != 0;
1299            reply->writeInt32(setLowRamDevice(isLowRamDevice));
1300            return NO_ERROR;
1301        } break;
1302        case LIST_AUDIO_PORTS: {
1303            CHECK_INTERFACE(IAudioFlinger, data, reply);
1304            unsigned int num_ports = data.readInt32();
1305            struct audio_port *ports =
1306                    (struct audio_port *)calloc(num_ports,
1307                                                           sizeof(struct audio_port));
1308            status_t status = listAudioPorts(&num_ports, ports);
1309            reply->writeInt32(status);
1310            if (status == NO_ERROR) {
1311                reply->writeInt32(num_ports);
1312                reply->write(&ports, num_ports * sizeof(struct audio_port));
1313            }
1314            free(ports);
1315            return NO_ERROR;
1316        } break;
1317        case GET_AUDIO_PORT: {
1318            CHECK_INTERFACE(IAudioFlinger, data, reply);
1319            struct audio_port port;
1320            data.read(&port, sizeof(struct audio_port));
1321            status_t status = getAudioPort(&port);
1322            reply->writeInt32(status);
1323            if (status == NO_ERROR) {
1324                reply->write(&port, sizeof(struct audio_port));
1325            }
1326            return NO_ERROR;
1327        } break;
1328        case CREATE_AUDIO_PATCH: {
1329            CHECK_INTERFACE(IAudioFlinger, data, reply);
1330            struct audio_patch patch;
1331            data.read(&patch, sizeof(struct audio_patch));
1332            audio_patch_handle_t handle;
1333            data.read(&handle, sizeof(audio_patch_handle_t));
1334            status_t status = createAudioPatch(&patch, &handle);
1335            reply->writeInt32(status);
1336            if (status == NO_ERROR) {
1337                reply->write(&handle, sizeof(audio_patch_handle_t));
1338            }
1339            return NO_ERROR;
1340        } break;
1341        case RELEASE_AUDIO_PATCH: {
1342            CHECK_INTERFACE(IAudioFlinger, data, reply);
1343            audio_patch_handle_t handle;
1344            data.read(&handle, sizeof(audio_patch_handle_t));
1345            status_t status = releaseAudioPatch(handle);
1346            reply->writeInt32(status);
1347            return NO_ERROR;
1348        } break;
1349        case LIST_AUDIO_PATCHES: {
1350            CHECK_INTERFACE(IAudioFlinger, data, reply);
1351            unsigned int num_patches = data.readInt32();
1352            struct audio_patch *patches =
1353                    (struct audio_patch *)calloc(num_patches,
1354                                                 sizeof(struct audio_patch));
1355            status_t status = listAudioPatches(&num_patches, patches);
1356            reply->writeInt32(status);
1357            if (status == NO_ERROR) {
1358                reply->writeInt32(num_patches);
1359                reply->write(&patches, num_patches * sizeof(struct audio_patch));
1360            }
1361            free(patches);
1362            return NO_ERROR;
1363        } break;
1364        case SET_AUDIO_PORT_CONFIG: {
1365            CHECK_INTERFACE(IAudioFlinger, data, reply);
1366            struct audio_port_config config;
1367            data.read(&config, sizeof(struct audio_port_config));
1368            status_t status = setAudioPortConfig(&config);
1369            reply->writeInt32(status);
1370            return NO_ERROR;
1371        } break;
1372        default:
1373            return BBinder::onTransact(code, data, reply, flags);
1374    }
1375}
1376
1377// ----------------------------------------------------------------------------
1378
1379}; // namespace android
1380