IAudioFlinger.cpp revision c2f1f07084818942352c6bbfb36af9b6b330eb4e
1/* //device/extlibs/pv/android/IAudioflinger.cpp
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    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    IS_MUSIC_ACTIVE,
51    SET_PARAMETERS,
52    GET_PARAMETERS,
53    REGISTER_CLIENT,
54    GET_INPUTBUFFERSIZE,
55    OPEN_OUTPUT,
56    OPEN_DUPLICATE_OUTPUT,
57    CLOSE_OUTPUT,
58    SUSPEND_OUTPUT,
59    RESTORE_OUTPUT,
60    OPEN_INPUT,
61    CLOSE_INPUT,
62    SET_STREAM_OUTPUT
63};
64
65class BpAudioFlinger : public BpInterface<IAudioFlinger>
66{
67public:
68    BpAudioFlinger(const sp<IBinder>& impl)
69        : BpInterface<IAudioFlinger>(impl)
70    {
71    }
72
73    virtual sp<IAudioTrack> createTrack(
74                                pid_t pid,
75                                int streamType,
76                                uint32_t sampleRate,
77                                int format,
78                                int channelCount,
79                                int frameCount,
80                                uint32_t flags,
81                                const sp<IMemory>& sharedBuffer,
82                                void *output,
83                                status_t *status)
84    {
85        Parcel data, reply;
86        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
87        data.writeInt32(pid);
88        data.writeInt32(streamType);
89        data.writeInt32(sampleRate);
90        data.writeInt32(format);
91        data.writeInt32(channelCount);
92        data.writeInt32(frameCount);
93        data.writeInt32(flags);
94        data.writeStrongBinder(sharedBuffer->asBinder());
95        data.write(&output, sizeof(void *));
96        status_t lStatus = remote()->transact(CREATE_TRACK, data, &reply);
97        if (lStatus != NO_ERROR) {
98            LOGE("createTrack error: %s", strerror(-lStatus));
99        }
100        lStatus = reply.readInt32();
101        if (status) {
102            *status = lStatus;
103        }
104        return interface_cast<IAudioTrack>(reply.readStrongBinder());
105    }
106
107    virtual sp<IAudioRecord> openRecord(
108                                pid_t pid,
109                                void *input,
110                                uint32_t sampleRate,
111                                int format,
112                                int channelCount,
113                                int frameCount,
114                                uint32_t flags,
115                                status_t *status)
116    {
117        Parcel data, reply;
118        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
119        data.writeInt32(pid);
120        data.write(&input, sizeof(void *));
121        data.writeInt32(sampleRate);
122        data.writeInt32(format);
123        data.writeInt32(channelCount);
124        data.writeInt32(frameCount);
125        data.writeInt32(flags);
126        remote()->transact(OPEN_RECORD, data, &reply);
127        status_t lStatus = reply.readInt32();
128        if (status) {
129            *status = lStatus;
130        }
131        return interface_cast<IAudioRecord>(reply.readStrongBinder());
132    }
133
134    virtual uint32_t sampleRate(void *output) const
135    {
136        Parcel data, reply;
137        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
138        data.write(&output, sizeof(void *));
139        remote()->transact(SAMPLE_RATE, data, &reply);
140        return reply.readInt32();
141    }
142
143    virtual int channelCount(void *output) const
144    {
145        Parcel data, reply;
146        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
147        data.write(&output, sizeof(void *));
148        remote()->transact(CHANNEL_COUNT, data, &reply);
149        return reply.readInt32();
150    }
151
152    virtual int format(void *output) const
153    {
154        Parcel data, reply;
155        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
156        data.write(&output, sizeof(void *));
157        remote()->transact(FORMAT, data, &reply);
158        return reply.readInt32();
159    }
160
161    virtual size_t frameCount(void *output) const
162    {
163        Parcel data, reply;
164        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
165        data.write(&output, sizeof(void *));
166        remote()->transact(FRAME_COUNT, data, &reply);
167        return reply.readInt32();
168    }
169
170    virtual uint32_t latency(void *output) const
171    {
172        Parcel data, reply;
173        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
174        data.write(&output, sizeof(void *));
175        remote()->transact(LATENCY, data, &reply);
176        return reply.readInt32();
177    }
178
179    virtual status_t setMasterVolume(float value)
180    {
181        Parcel data, reply;
182        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
183        data.writeFloat(value);
184        remote()->transact(SET_MASTER_VOLUME, data, &reply);
185        return reply.readInt32();
186    }
187
188    virtual status_t setMasterMute(bool muted)
189    {
190        Parcel data, reply;
191        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
192        data.writeInt32(muted);
193        remote()->transact(SET_MASTER_MUTE, data, &reply);
194        return reply.readInt32();
195    }
196
197    virtual float masterVolume() const
198    {
199        Parcel data, reply;
200        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
201        remote()->transact(MASTER_VOLUME, data, &reply);
202        return reply.readFloat();
203    }
204
205    virtual bool masterMute() const
206    {
207        Parcel data, reply;
208        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
209        remote()->transact(MASTER_MUTE, data, &reply);
210        return reply.readInt32();
211    }
212
213    virtual status_t setStreamVolume(int stream, float value, void *output)
214    {
215        Parcel data, reply;
216        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
217        data.writeInt32(stream);
218        data.writeFloat(value);
219        data.write(&output, sizeof(void *));
220        remote()->transact(SET_STREAM_VOLUME, data, &reply);
221        return reply.readInt32();
222    }
223
224    virtual status_t setStreamMute(int stream, bool muted)
225    {
226        Parcel data, reply;
227        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
228        data.writeInt32(stream);
229        data.writeInt32(muted);
230        remote()->transact(SET_STREAM_MUTE, data, &reply);
231        return reply.readInt32();
232    }
233
234    virtual float streamVolume(int stream, void *output) const
235    {
236        Parcel data, reply;
237        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
238        data.writeInt32(stream);
239        data.write(&output, sizeof(void *));
240        remote()->transact(STREAM_VOLUME, data, &reply);
241        return reply.readFloat();
242    }
243
244    virtual bool streamMute(int stream) const
245    {
246        Parcel data, reply;
247        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
248        data.writeInt32(stream);
249        remote()->transact(STREAM_MUTE, data, &reply);
250        return reply.readInt32();
251    }
252
253    virtual status_t setMode(int mode)
254    {
255        Parcel data, reply;
256        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
257        data.writeInt32(mode);
258        remote()->transact(SET_MODE, data, &reply);
259        return reply.readInt32();
260    }
261
262    virtual status_t setMicMute(bool state)
263    {
264        Parcel data, reply;
265        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
266        data.writeInt32(state);
267        remote()->transact(SET_MIC_MUTE, data, &reply);
268        return reply.readInt32();
269    }
270
271    virtual bool getMicMute() const
272    {
273        Parcel data, reply;
274        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
275        remote()->transact(GET_MIC_MUTE, data, &reply);
276        return reply.readInt32();
277    }
278
279    virtual bool isMusicActive() const
280    {
281        Parcel data, reply;
282        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
283        remote()->transact(IS_MUSIC_ACTIVE, data, &reply);
284        return reply.readInt32();
285    }
286
287    virtual status_t setParameters(void *ioHandle, const String8& keyValuePairs)
288    {
289        Parcel data, reply;
290        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
291        data.write(&ioHandle, sizeof(void *));
292        data.writeString8(keyValuePairs);
293        remote()->transact(SET_PARAMETERS, data, &reply);
294        return reply.readInt32();
295    }
296
297    virtual String8 getParameters(void *ioHandle, const String8& keys)
298    {
299        Parcel data, reply;
300        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
301        data.write(&ioHandle, sizeof(void *));
302        data.writeString8(keys);
303        remote()->transact(GET_PARAMETERS, data, &reply);
304        return reply.readString8();
305    }
306
307    virtual void registerClient(const sp<IAudioFlingerClient>& client)
308    {
309        Parcel data, reply;
310        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
311        data.writeStrongBinder(client->asBinder());
312        remote()->transact(REGISTER_CLIENT, data, &reply);
313    }
314
315    virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
316    {
317        Parcel data, reply;
318        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
319        data.writeInt32(sampleRate);
320        data.writeInt32(format);
321        data.writeInt32(channelCount);
322        remote()->transact(GET_INPUTBUFFERSIZE, data, &reply);
323        return reply.readInt32();
324    }
325
326    virtual void *openOutput(uint32_t *pDevices,
327                            uint32_t *pSamplingRate,
328                            uint32_t *pFormat,
329                            uint32_t *pChannels,
330                            uint32_t *pLatencyMs,
331                            uint32_t flags)
332    {
333        Parcel data, reply;
334        uint32_t devices = pDevices ? *pDevices : 0;
335        uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0;
336        uint32_t format = pFormat ? *pFormat : 0;
337        uint32_t channels = pChannels ? *pChannels : 0;
338        uint32_t latency = pLatencyMs ? *pLatencyMs : 0;
339
340        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
341        data.writeInt32(devices);
342        data.writeInt32(samplingRate);
343        data.writeInt32(format);
344        data.writeInt32(channels);
345        data.writeInt32(latency);
346        data.writeInt32(flags);
347        remote()->transact(OPEN_OUTPUT, data, &reply);
348        void *output;
349        reply.read(&output, sizeof(void *));
350        LOGV("openOutput() returned output, %p", output);
351        devices = reply.readInt32();
352        if (pDevices) *pDevices = devices;
353        samplingRate = reply.readInt32();
354        if (pSamplingRate) *pSamplingRate = samplingRate;
355        format = reply.readInt32();
356        if (pFormat) *pFormat = format;
357        channels = reply.readInt32();
358        if (pChannels) *pChannels = channels;
359        latency = reply.readInt32();
360        if (pLatencyMs) *pLatencyMs = latency;
361        return output;
362    }
363
364    virtual void *openDuplicateOutput(void *output1, void *output2)
365    {
366        Parcel data, reply;
367        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
368        data.write(&output1, sizeof(void *));
369        data.write(&output2, sizeof(void *));
370        remote()->transact(OPEN_DUPLICATE_OUTPUT, data, &reply);
371        void *output;
372        reply.read(&output, sizeof(void *));
373        return output;
374    }
375
376    virtual status_t closeOutput(void *output)
377    {
378        Parcel data, reply;
379        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
380        data.write(&output, sizeof(void *));
381        remote()->transact(CLOSE_OUTPUT, data, &reply);
382        return reply.readInt32();
383    }
384
385    virtual status_t suspendOutput(void *output)
386    {
387        Parcel data, reply;
388        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
389        data.write(&output, sizeof(void *));
390        remote()->transact(SUSPEND_OUTPUT, data, &reply);
391        return reply.readInt32();
392    }
393
394    virtual status_t restoreOutput(void *output)
395    {
396        Parcel data, reply;
397        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
398        data.write(&output, sizeof(void *));
399        remote()->transact(RESTORE_OUTPUT, data, &reply);
400        return reply.readInt32();
401    }
402
403    virtual void *openInput(uint32_t *pDevices,
404                                        uint32_t *pSamplingRate,
405                                        uint32_t *pFormat,
406                                        uint32_t *pChannels,
407                                        uint32_t acoustics)
408    {
409        Parcel data, reply;
410        uint32_t devices = pDevices ? *pDevices : 0;
411        uint32_t samplingRate = pSamplingRate ? *pSamplingRate : 0;
412        uint32_t format = pFormat ? *pFormat : 0;
413        uint32_t channels = pChannels ? *pChannels : 0;
414
415        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
416        data.writeInt32(devices);
417        data.writeInt32(samplingRate);
418        data.writeInt32(format);
419        data.writeInt32(channels);
420        data.writeInt32(acoustics);
421        remote()->transact(OPEN_INPUT, data, &reply);
422        void *input;
423        reply.read(&input, sizeof(void *));
424        devices = reply.readInt32();
425        if (pDevices) *pDevices = devices;
426        samplingRate = reply.readInt32();
427        if (pSamplingRate) *pSamplingRate = samplingRate;
428        format = reply.readInt32();
429        if (pFormat) *pFormat = format;
430        channels = reply.readInt32();
431        if (pChannels) *pChannels = channels;
432        return input;
433    }
434
435    virtual status_t closeInput(void *input)
436    {
437        Parcel data, reply;
438        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
439        data.write(&input, sizeof(void *));
440        remote()->transact(CLOSE_INPUT, data, &reply);
441        return reply.readInt32();
442    }
443
444    virtual status_t setStreamOutput(uint32_t stream, void *output)
445    {
446        Parcel data, reply;
447        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
448        data.writeInt32(stream);
449        data.write(&output, sizeof(void *));
450        remote()->transact(SET_STREAM_OUTPUT, data, &reply);
451        return reply.readInt32();
452    }
453};
454
455IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
456
457// ----------------------------------------------------------------------
458
459status_t BnAudioFlinger::onTransact(
460    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
461{
462    switch(code) {
463        case CREATE_TRACK: {
464            CHECK_INTERFACE(IAudioFlinger, data, reply);
465            pid_t pid = data.readInt32();
466            int streamType = data.readInt32();
467            uint32_t sampleRate = data.readInt32();
468            int format = data.readInt32();
469            int channelCount = data.readInt32();
470            size_t bufferCount = data.readInt32();
471            uint32_t flags = data.readInt32();
472            sp<IMemory> buffer = interface_cast<IMemory>(data.readStrongBinder());
473            void *output;
474            data.read(&output, sizeof(void *));
475            status_t status;
476            sp<IAudioTrack> track = createTrack(pid,
477                    streamType, sampleRate, format,
478                    channelCount, bufferCount, flags, buffer, output, &status);
479            reply->writeInt32(status);
480            reply->writeStrongBinder(track->asBinder());
481            return NO_ERROR;
482        } break;
483        case OPEN_RECORD: {
484            CHECK_INTERFACE(IAudioFlinger, data, reply);
485            pid_t pid = data.readInt32();
486            void *input;
487            data.read(&input, sizeof(void *));
488            uint32_t sampleRate = data.readInt32();
489            int format = data.readInt32();
490            int channelCount = data.readInt32();
491            size_t bufferCount = data.readInt32();
492            uint32_t flags = data.readInt32();
493            status_t status;
494            sp<IAudioRecord> record = openRecord(pid, input,
495                    sampleRate, format, channelCount, bufferCount, flags, &status);
496            reply->writeInt32(status);
497            reply->writeStrongBinder(record->asBinder());
498            return NO_ERROR;
499        } break;
500        case SAMPLE_RATE: {
501            CHECK_INTERFACE(IAudioFlinger, data, reply);
502            void *output;
503            data.read(&output, sizeof(void *));
504            reply->writeInt32( sampleRate(output) );
505            return NO_ERROR;
506        } break;
507        case CHANNEL_COUNT: {
508            CHECK_INTERFACE(IAudioFlinger, data, reply);
509            void *output;
510            data.read(&output, sizeof(void *));
511            reply->writeInt32( channelCount(output) );
512            return NO_ERROR;
513        } break;
514        case FORMAT: {
515            CHECK_INTERFACE(IAudioFlinger, data, reply);
516            void *output;
517            data.read(&output, sizeof(void *));
518            reply->writeInt32( format(output) );
519            return NO_ERROR;
520        } break;
521        case FRAME_COUNT: {
522            CHECK_INTERFACE(IAudioFlinger, data, reply);
523            void *output;
524            data.read(&output, sizeof(void *));
525            reply->writeInt32( frameCount(output) );
526            return NO_ERROR;
527        } break;
528        case LATENCY: {
529            CHECK_INTERFACE(IAudioFlinger, data, reply);
530            void *output;
531            data.read(&output, sizeof(void *));
532            reply->writeInt32( latency(output) );
533            return NO_ERROR;
534        } break;
535         case SET_MASTER_VOLUME: {
536            CHECK_INTERFACE(IAudioFlinger, data, reply);
537            reply->writeInt32( setMasterVolume(data.readFloat()) );
538            return NO_ERROR;
539        } break;
540        case SET_MASTER_MUTE: {
541            CHECK_INTERFACE(IAudioFlinger, data, reply);
542            reply->writeInt32( setMasterMute(data.readInt32()) );
543            return NO_ERROR;
544        } break;
545        case MASTER_VOLUME: {
546            CHECK_INTERFACE(IAudioFlinger, data, reply);
547            reply->writeFloat( masterVolume() );
548            return NO_ERROR;
549        } break;
550        case MASTER_MUTE: {
551            CHECK_INTERFACE(IAudioFlinger, data, reply);
552            reply->writeInt32( masterMute() );
553            return NO_ERROR;
554        } break;
555        case SET_STREAM_VOLUME: {
556            CHECK_INTERFACE(IAudioFlinger, data, reply);
557            int stream = data.readInt32();
558            float volume = data.readFloat();
559            void *output;
560            data.read(&output, sizeof(void *));
561            reply->writeInt32( setStreamVolume(stream, volume, output) );
562            return NO_ERROR;
563        } break;
564        case SET_STREAM_MUTE: {
565            CHECK_INTERFACE(IAudioFlinger, data, reply);
566            int stream = data.readInt32();
567            reply->writeInt32( setStreamMute(stream, data.readInt32()) );
568            return NO_ERROR;
569        } break;
570        case STREAM_VOLUME: {
571            CHECK_INTERFACE(IAudioFlinger, data, reply);
572            int stream = data.readInt32();
573            void *output;
574            data.read(&output, sizeof(void *));
575            reply->writeFloat( streamVolume(stream, output) );
576            return NO_ERROR;
577        } break;
578        case STREAM_MUTE: {
579            CHECK_INTERFACE(IAudioFlinger, data, reply);
580            int stream = data.readInt32();
581            reply->writeInt32( streamMute(stream) );
582            return NO_ERROR;
583        } break;
584        case SET_MODE: {
585            CHECK_INTERFACE(IAudioFlinger, data, reply);
586            int mode = data.readInt32();
587            reply->writeInt32( setMode(mode) );
588            return NO_ERROR;
589        } break;
590        case SET_MIC_MUTE: {
591            CHECK_INTERFACE(IAudioFlinger, data, reply);
592            int state = data.readInt32();
593            reply->writeInt32( setMicMute(state) );
594            return NO_ERROR;
595        } break;
596        case GET_MIC_MUTE: {
597            CHECK_INTERFACE(IAudioFlinger, data, reply);
598            reply->writeInt32( getMicMute() );
599            return NO_ERROR;
600        } break;
601        case IS_MUSIC_ACTIVE: {
602            CHECK_INTERFACE(IAudioFlinger, data, reply);
603            reply->writeInt32( isMusicActive() );
604            return NO_ERROR;
605        } break;
606        case SET_PARAMETERS: {
607            CHECK_INTERFACE(IAudioFlinger, data, reply);
608            void *ioHandle;
609            data.read(&ioHandle, sizeof(void *));
610            String8 keyValuePairs(data.readString8());
611            reply->writeInt32(setParameters(ioHandle, keyValuePairs));
612            return NO_ERROR;
613         } break;
614        case GET_PARAMETERS: {
615            CHECK_INTERFACE(IAudioFlinger, data, reply);
616            void *ioHandle;
617            data.read(&ioHandle, sizeof(void *));
618            String8 keys(data.readString8());
619            reply->writeString8(getParameters(ioHandle, keys));
620            return NO_ERROR;
621         } break;
622
623        case REGISTER_CLIENT: {
624            CHECK_INTERFACE(IAudioFlinger, data, reply);
625            sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient>(data.readStrongBinder());
626            registerClient(client);
627            return NO_ERROR;
628        } break;
629        case GET_INPUTBUFFERSIZE: {
630            CHECK_INTERFACE(IAudioFlinger, data, reply);
631            uint32_t sampleRate = data.readInt32();
632            int format = data.readInt32();
633            int channelCount = data.readInt32();
634            reply->writeInt32( getInputBufferSize(sampleRate, format, channelCount) );
635            return NO_ERROR;
636        } break;
637        case OPEN_OUTPUT: {
638            CHECK_INTERFACE(IAudioFlinger, data, reply);
639            uint32_t devices = data.readInt32();
640            uint32_t samplingRate = data.readInt32();
641            uint32_t format = data.readInt32();
642            uint32_t channels = data.readInt32();
643            uint32_t latency = data.readInt32();
644            uint32_t flags = data.readInt32();
645            void *output = openOutput(&devices,
646                                     &samplingRate,
647                                     &format,
648                                     &channels,
649                                     &latency,
650                                     flags);
651            LOGV("OPEN_OUTPUT output, %p", output);
652            reply->write(&output, sizeof(void *));
653            reply->writeInt32(devices);
654            reply->writeInt32(samplingRate);
655            reply->writeInt32(format);
656            reply->writeInt32(channels);
657            reply->writeInt32(latency);
658            return NO_ERROR;
659        } break;
660        case OPEN_DUPLICATE_OUTPUT: {
661            CHECK_INTERFACE(IAudioFlinger, data, reply);
662            void *output1;
663            void *output2;
664            data.read(&output1, sizeof(void *));
665            data.read(&output2, sizeof(void *));
666            void *output = openDuplicateOutput(output1, output2);
667            reply->write(&output, sizeof(void *));
668            return NO_ERROR;
669        } break;
670        case CLOSE_OUTPUT: {
671            CHECK_INTERFACE(IAudioFlinger, data, reply);
672            void *output;
673            data.read(&output, sizeof(void *));
674            reply->writeInt32(closeOutput(output));
675            return NO_ERROR;
676        } break;
677        case SUSPEND_OUTPUT: {
678            CHECK_INTERFACE(IAudioFlinger, data, reply);
679            void *output;
680            data.read(&output, sizeof(void *));
681            reply->writeInt32(suspendOutput(output));
682            return NO_ERROR;
683        } break;
684        case RESTORE_OUTPUT: {
685            CHECK_INTERFACE(IAudioFlinger, data, reply);
686            void *output;
687            data.read(&output, sizeof(void *));
688            reply->writeInt32(restoreOutput(output));
689            return NO_ERROR;
690        } break;
691        case OPEN_INPUT: {
692            CHECK_INTERFACE(IAudioFlinger, data, reply);
693            uint32_t devices = data.readInt32();
694            uint32_t samplingRate = data.readInt32();
695            uint32_t format = data.readInt32();
696            uint32_t channels = data.readInt32();
697            uint32_t acoutics = data.readInt32();
698
699            void *input = openInput(&devices,
700                                     &samplingRate,
701                                     &format,
702                                     &channels,
703                                     acoutics);
704            reply->write(&input, sizeof(void *));
705            reply->writeInt32(devices);
706            reply->writeInt32(samplingRate);
707            reply->writeInt32(format);
708            reply->writeInt32(channels);
709            return NO_ERROR;
710        } break;
711        case CLOSE_INPUT: {
712            CHECK_INTERFACE(IAudioFlinger, data, reply);
713            void *input;
714            data.read(&input, sizeof(void *));
715            reply->writeInt32(closeInput(input));
716            return NO_ERROR;
717        } break;
718        case SET_STREAM_OUTPUT: {
719            CHECK_INTERFACE(IAudioFlinger, data, reply);
720            void *output;
721            uint32_t stream = data.readInt32();
722            data.read(&output, sizeof(void *));
723            reply->writeInt32(setStreamOutput(stream, output));
724            return NO_ERROR;
725        } break;
726        default:
727            return BBinder::onTransact(code, data, reply, flags);
728    }
729}
730
731// ----------------------------------------------------------------------------
732
733}; // namespace android
734