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