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