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