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