IAudioFlinger.cpp revision 507b2860cfe0bb4a712064f1c503caa9a7325886
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    SET_STREAM_OUTPUT,
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};
78
79class BpAudioFlinger : public BpInterface<IAudioFlinger>
80{
81public:
82    BpAudioFlinger(const sp<IBinder>& impl)
83        : BpInterface<IAudioFlinger>(impl)
84    {
85    }
86
87    virtual sp<IAudioTrack> createTrack(
88                                audio_stream_type_t streamType,
89                                uint32_t sampleRate,
90                                audio_format_t format,
91                                audio_channel_mask_t channelMask,
92                                size_t frameCount,
93                                track_flags_t *flags,
94                                const sp<IMemory>& sharedBuffer,
95                                audio_io_handle_t output,
96                                pid_t tid,
97                                int *sessionId,
98                                String8& name,
99                                status_t *status)
100    {
101        Parcel data, reply;
102        sp<IAudioTrack> track;
103        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
104        data.writeInt32((int32_t) streamType);
105        data.writeInt32(sampleRate);
106        data.writeInt32(format);
107        data.writeInt32(channelMask);
108        data.writeInt32(frameCount);
109        track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT;
110        data.writeInt32(lFlags);
111        data.writeStrongBinder(sharedBuffer->asBinder());
112        data.writeInt32((int32_t) output);
113        data.writeInt32((int32_t) tid);
114        int lSessionId = 0;
115        if (sessionId != NULL) {
116            lSessionId = *sessionId;
117        }
118        data.writeInt32(lSessionId);
119        status_t lStatus = remote()->transact(CREATE_TRACK, data, &reply);
120        if (lStatus != NO_ERROR) {
121            ALOGE("createTrack error: %s", strerror(-lStatus));
122        } else {
123            lFlags = reply.readInt32();
124            if (flags != NULL) {
125                *flags = lFlags;
126            }
127            lSessionId = reply.readInt32();
128            if (sessionId != NULL) {
129                *sessionId = lSessionId;
130            }
131            name = reply.readString8();
132            lStatus = reply.readInt32();
133            track = interface_cast<IAudioTrack>(reply.readStrongBinder());
134        }
135        if (status != NULL) {
136            *status = lStatus;
137        }
138        return track;
139    }
140
141    virtual sp<IAudioRecord> openRecord(
142                                audio_io_handle_t input,
143                                uint32_t sampleRate,
144                                audio_format_t format,
145                                audio_channel_mask_t channelMask,
146                                size_t frameCount,
147                                track_flags_t *flags,
148                                pid_t tid,
149                                int *sessionId,
150                                status_t *status)
151    {
152        Parcel data, reply;
153        sp<IAudioRecord> record;
154        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
155        data.writeInt32((int32_t) input);
156        data.writeInt32(sampleRate);
157        data.writeInt32(format);
158        data.writeInt32(channelMask);
159        data.writeInt32(frameCount);
160        track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT;
161        data.writeInt32(lFlags);
162        data.writeInt32((int32_t) tid);
163        int lSessionId = 0;
164        if (sessionId != NULL) {
165            lSessionId = *sessionId;
166        }
167        data.writeInt32(lSessionId);
168        status_t lStatus = remote()->transact(OPEN_RECORD, data, &reply);
169        if (lStatus != NO_ERROR) {
170            ALOGE("openRecord error: %s", strerror(-lStatus));
171        } else {
172            lFlags = reply.readInt32();
173            if (flags != NULL) {
174                *flags = lFlags;
175            }
176            lSessionId = reply.readInt32();
177            if (sessionId != NULL) {
178                *sessionId = lSessionId;
179            }
180            lStatus = reply.readInt32();
181            record = interface_cast<IAudioRecord>(reply.readStrongBinder());
182        }
183        if (status != NULL) {
184            *status = lStatus;
185        }
186        return record;
187    }
188
189    virtual uint32_t sampleRate(audio_io_handle_t output) const
190    {
191        Parcel data, reply;
192        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
193        data.writeInt32((int32_t) output);
194        remote()->transact(SAMPLE_RATE, data, &reply);
195        return reply.readInt32();
196    }
197
198    virtual audio_format_t format(audio_io_handle_t output) const
199    {
200        Parcel data, reply;
201        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
202        data.writeInt32((int32_t) output);
203        remote()->transact(FORMAT, data, &reply);
204        return (audio_format_t) reply.readInt32();
205    }
206
207    virtual size_t frameCount(audio_io_handle_t output) const
208    {
209        Parcel data, reply;
210        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
211        data.writeInt32((int32_t) output);
212        remote()->transact(FRAME_COUNT, data, &reply);
213        return reply.readInt32();
214    }
215
216    virtual uint32_t latency(audio_io_handle_t output) const
217    {
218        Parcel data, reply;
219        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
220        data.writeInt32((int32_t) output);
221        remote()->transact(LATENCY, data, &reply);
222        return reply.readInt32();
223    }
224
225    virtual status_t setMasterVolume(float value)
226    {
227        Parcel data, reply;
228        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
229        data.writeFloat(value);
230        remote()->transact(SET_MASTER_VOLUME, data, &reply);
231        return reply.readInt32();
232    }
233
234    virtual status_t setMasterMute(bool muted)
235    {
236        Parcel data, reply;
237        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
238        data.writeInt32(muted);
239        remote()->transact(SET_MASTER_MUTE, data, &reply);
240        return reply.readInt32();
241    }
242
243    virtual float masterVolume() const
244    {
245        Parcel data, reply;
246        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
247        remote()->transact(MASTER_VOLUME, data, &reply);
248        return reply.readFloat();
249    }
250
251    virtual bool masterMute() const
252    {
253        Parcel data, reply;
254        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
255        remote()->transact(MASTER_MUTE, data, &reply);
256        return reply.readInt32();
257    }
258
259    virtual status_t setStreamVolume(audio_stream_type_t stream, float value,
260            audio_io_handle_t output)
261    {
262        Parcel data, reply;
263        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
264        data.writeInt32((int32_t) stream);
265        data.writeFloat(value);
266        data.writeInt32((int32_t) output);
267        remote()->transact(SET_STREAM_VOLUME, data, &reply);
268        return reply.readInt32();
269    }
270
271    virtual status_t setStreamMute(audio_stream_type_t stream, bool muted)
272    {
273        Parcel data, reply;
274        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
275        data.writeInt32((int32_t) stream);
276        data.writeInt32(muted);
277        remote()->transact(SET_STREAM_MUTE, data, &reply);
278        return reply.readInt32();
279    }
280
281    virtual float streamVolume(audio_stream_type_t stream, audio_io_handle_t output) const
282    {
283        Parcel data, reply;
284        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
285        data.writeInt32((int32_t) stream);
286        data.writeInt32((int32_t) output);
287        remote()->transact(STREAM_VOLUME, data, &reply);
288        return reply.readFloat();
289    }
290
291    virtual bool streamMute(audio_stream_type_t stream) const
292    {
293        Parcel data, reply;
294        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
295        data.writeInt32((int32_t) stream);
296        remote()->transact(STREAM_MUTE, data, &reply);
297        return reply.readInt32();
298    }
299
300    virtual status_t setMode(audio_mode_t mode)
301    {
302        Parcel data, reply;
303        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
304        data.writeInt32(mode);
305        remote()->transact(SET_MODE, data, &reply);
306        return reply.readInt32();
307    }
308
309    virtual status_t setMicMute(bool state)
310    {
311        Parcel data, reply;
312        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
313        data.writeInt32(state);
314        remote()->transact(SET_MIC_MUTE, data, &reply);
315        return reply.readInt32();
316    }
317
318    virtual bool getMicMute() const
319    {
320        Parcel data, reply;
321        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
322        remote()->transact(GET_MIC_MUTE, data, &reply);
323        return reply.readInt32();
324    }
325
326    virtual status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
327    {
328        Parcel data, reply;
329        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
330        data.writeInt32((int32_t) ioHandle);
331        data.writeString8(keyValuePairs);
332        remote()->transact(SET_PARAMETERS, data, &reply);
333        return reply.readInt32();
334    }
335
336    virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) const
337    {
338        Parcel data, reply;
339        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
340        data.writeInt32((int32_t) ioHandle);
341        data.writeString8(keys);
342        remote()->transact(GET_PARAMETERS, data, &reply);
343        return reply.readString8();
344    }
345
346    virtual void registerClient(const sp<IAudioFlingerClient>& client)
347    {
348        Parcel data, reply;
349        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
350        data.writeStrongBinder(client->asBinder());
351        remote()->transact(REGISTER_CLIENT, data, &reply);
352    }
353
354    virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
355            audio_channel_mask_t channelMask) const
356    {
357        Parcel data, reply;
358        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
359        data.writeInt32(sampleRate);
360        data.writeInt32(format);
361        data.writeInt32(channelMask);
362        remote()->transact(GET_INPUTBUFFERSIZE, data, &reply);
363        return reply.readInt32();
364    }
365
366    virtual audio_io_handle_t openOutput(audio_module_handle_t module,
367                                         audio_devices_t *pDevices,
368                                         uint32_t *pSamplingRate,
369                                         audio_format_t *pFormat,
370                                         audio_channel_mask_t *pChannelMask,
371                                         uint32_t *pLatencyMs,
372                                         audio_output_flags_t flags,
373                                         const audio_offload_info_t *offloadInfo)
374    {
375        Parcel data, reply;
376        audio_devices_t devices = pDevices != NULL ? *pDevices : (audio_devices_t)0;
377        uint32_t samplingRate = pSamplingRate != NULL ? *pSamplingRate : 0;
378        audio_format_t format = pFormat != NULL ? *pFormat : AUDIO_FORMAT_DEFAULT;
379        audio_channel_mask_t channelMask = pChannelMask != NULL ?
380                *pChannelMask : (audio_channel_mask_t)0;
381        uint32_t latency = pLatencyMs != NULL ? *pLatencyMs : 0;
382        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
383        data.writeInt32(module);
384        data.writeInt32(devices);
385        data.writeInt32(samplingRate);
386        data.writeInt32(format);
387        data.writeInt32(channelMask);
388        data.writeInt32(latency);
389        data.writeInt32((int32_t) flags);
390        if (offloadInfo == NULL) {
391            data.writeInt32(0);
392        } else {
393            data.writeInt32(1);
394            data.write(offloadInfo, sizeof(audio_offload_info_t));
395        }
396        remote()->transact(OPEN_OUTPUT, data, &reply);
397        audio_io_handle_t output = (audio_io_handle_t) reply.readInt32();
398        ALOGV("openOutput() returned output, %d", output);
399        devices = (audio_devices_t)reply.readInt32();
400        if (pDevices != NULL) {
401            *pDevices = devices;
402        }
403        samplingRate = reply.readInt32();
404        if (pSamplingRate != NULL) {
405            *pSamplingRate = samplingRate;
406        }
407        format = (audio_format_t) reply.readInt32();
408        if (pFormat != NULL) {
409            *pFormat = format;
410        }
411        channelMask = (audio_channel_mask_t)reply.readInt32();
412        if (pChannelMask != NULL) {
413            *pChannelMask = channelMask;
414        }
415        latency = reply.readInt32();
416        if (pLatencyMs != NULL) {
417            *pLatencyMs = latency;
418        }
419        return output;
420    }
421
422    virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
423            audio_io_handle_t output2)
424    {
425        Parcel data, reply;
426        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
427        data.writeInt32((int32_t) output1);
428        data.writeInt32((int32_t) output2);
429        remote()->transact(OPEN_DUPLICATE_OUTPUT, data, &reply);
430        return (audio_io_handle_t) reply.readInt32();
431    }
432
433    virtual status_t closeOutput(audio_io_handle_t output)
434    {
435        Parcel data, reply;
436        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
437        data.writeInt32((int32_t) output);
438        remote()->transact(CLOSE_OUTPUT, data, &reply);
439        return reply.readInt32();
440    }
441
442    virtual status_t suspendOutput(audio_io_handle_t output)
443    {
444        Parcel data, reply;
445        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
446        data.writeInt32((int32_t) output);
447        remote()->transact(SUSPEND_OUTPUT, data, &reply);
448        return reply.readInt32();
449    }
450
451    virtual status_t restoreOutput(audio_io_handle_t output)
452    {
453        Parcel data, reply;
454        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
455        data.writeInt32((int32_t) output);
456        remote()->transact(RESTORE_OUTPUT, data, &reply);
457        return reply.readInt32();
458    }
459
460    virtual audio_io_handle_t openInput(audio_module_handle_t module,
461                                        audio_devices_t *pDevices,
462                                        uint32_t *pSamplingRate,
463                                        audio_format_t *pFormat,
464                                        audio_channel_mask_t *pChannelMask)
465    {
466        Parcel data, reply;
467        audio_devices_t devices = pDevices != NULL ? *pDevices : (audio_devices_t)0;
468        uint32_t samplingRate = pSamplingRate != NULL ? *pSamplingRate : 0;
469        audio_format_t format = pFormat != NULL ? *pFormat : AUDIO_FORMAT_DEFAULT;
470        audio_channel_mask_t channelMask = pChannelMask != NULL ?
471                *pChannelMask : (audio_channel_mask_t)0;
472
473        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
474        data.writeInt32(module);
475        data.writeInt32(devices);
476        data.writeInt32(samplingRate);
477        data.writeInt32(format);
478        data.writeInt32(channelMask);
479        remote()->transact(OPEN_INPUT, data, &reply);
480        audio_io_handle_t input = (audio_io_handle_t) reply.readInt32();
481        devices = (audio_devices_t)reply.readInt32();
482        if (pDevices != NULL) {
483            *pDevices = devices;
484        }
485        samplingRate = reply.readInt32();
486        if (pSamplingRate != NULL) {
487            *pSamplingRate = samplingRate;
488        }
489        format = (audio_format_t) reply.readInt32();
490        if (pFormat != NULL) {
491            *pFormat = format;
492        }
493        channelMask = (audio_channel_mask_t)reply.readInt32();
494        if (pChannelMask != NULL) {
495            *pChannelMask = channelMask;
496        }
497        return input;
498    }
499
500    virtual status_t closeInput(int input)
501    {
502        Parcel data, reply;
503        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
504        data.writeInt32(input);
505        remote()->transact(CLOSE_INPUT, data, &reply);
506        return reply.readInt32();
507    }
508
509    virtual status_t setStreamOutput(audio_stream_type_t stream, audio_io_handle_t output)
510    {
511        Parcel data, reply;
512        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
513        data.writeInt32((int32_t) stream);
514        data.writeInt32((int32_t) output);
515        remote()->transact(SET_STREAM_OUTPUT, data, &reply);
516        return reply.readInt32();
517    }
518
519    virtual status_t setVoiceVolume(float volume)
520    {
521        Parcel data, reply;
522        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
523        data.writeFloat(volume);
524        remote()->transact(SET_VOICE_VOLUME, data, &reply);
525        return reply.readInt32();
526    }
527
528    virtual status_t getRenderPosition(size_t *halFrames, size_t *dspFrames,
529            audio_io_handle_t output) const
530    {
531        Parcel data, reply;
532        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
533        data.writeInt32((int32_t) output);
534        remote()->transact(GET_RENDER_POSITION, data, &reply);
535        status_t status = reply.readInt32();
536        if (status == NO_ERROR) {
537            uint32_t tmp = reply.readInt32();
538            if (halFrames != NULL) {
539                *halFrames = tmp;
540            }
541            tmp = reply.readInt32();
542            if (dspFrames != NULL) {
543                *dspFrames = tmp;
544            }
545        }
546        return status;
547    }
548
549    virtual size_t getInputFramesLost(audio_io_handle_t ioHandle) const
550    {
551        Parcel data, reply;
552        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
553        data.writeInt32((int32_t) ioHandle);
554        remote()->transact(GET_INPUT_FRAMES_LOST, data, &reply);
555        return reply.readInt32();
556    }
557
558    virtual int newAudioSessionId()
559    {
560        Parcel data, reply;
561        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
562        status_t status = remote()->transact(NEW_AUDIO_SESSION_ID, data, &reply);
563        int id = 0;
564        if (status == NO_ERROR) {
565            id = reply.readInt32();
566        }
567        return id;
568    }
569
570    virtual void acquireAudioSessionId(int audioSession)
571    {
572        Parcel data, reply;
573        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
574        data.writeInt32(audioSession);
575        remote()->transact(ACQUIRE_AUDIO_SESSION_ID, data, &reply);
576    }
577
578    virtual void releaseAudioSessionId(int audioSession)
579    {
580        Parcel data, reply;
581        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
582        data.writeInt32(audioSession);
583        remote()->transact(RELEASE_AUDIO_SESSION_ID, data, &reply);
584    }
585
586    virtual status_t queryNumberEffects(uint32_t *numEffects) const
587    {
588        Parcel data, reply;
589        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
590        status_t status = remote()->transact(QUERY_NUM_EFFECTS, data, &reply);
591        if (status != NO_ERROR) {
592            return status;
593        }
594        status = reply.readInt32();
595        if (status != NO_ERROR) {
596            return status;
597        }
598        if (numEffects != NULL) {
599            *numEffects = (uint32_t)reply.readInt32();
600        }
601        return NO_ERROR;
602    }
603
604    virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) const
605    {
606        if (pDescriptor == NULL) {
607            return BAD_VALUE;
608        }
609        Parcel data, reply;
610        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
611        data.writeInt32(index);
612        status_t status = remote()->transact(QUERY_EFFECT, data, &reply);
613        if (status != NO_ERROR) {
614            return status;
615        }
616        status = reply.readInt32();
617        if (status != NO_ERROR) {
618            return status;
619        }
620        reply.read(pDescriptor, sizeof(effect_descriptor_t));
621        return NO_ERROR;
622    }
623
624    virtual status_t getEffectDescriptor(const effect_uuid_t *pUuid,
625            effect_descriptor_t *pDescriptor) const
626    {
627        if (pUuid == NULL || pDescriptor == NULL) {
628            return BAD_VALUE;
629        }
630        Parcel data, reply;
631        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
632        data.write(pUuid, sizeof(effect_uuid_t));
633        status_t status = remote()->transact(GET_EFFECT_DESCRIPTOR, data, &reply);
634        if (status != NO_ERROR) {
635            return status;
636        }
637        status = reply.readInt32();
638        if (status != NO_ERROR) {
639            return status;
640        }
641        reply.read(pDescriptor, sizeof(effect_descriptor_t));
642        return NO_ERROR;
643    }
644
645    virtual sp<IEffect> createEffect(
646                                    effect_descriptor_t *pDesc,
647                                    const sp<IEffectClient>& client,
648                                    int32_t priority,
649                                    audio_io_handle_t output,
650                                    int sessionId,
651                                    status_t *status,
652                                    int *id,
653                                    int *enabled)
654    {
655        Parcel data, reply;
656        sp<IEffect> effect;
657
658        if (pDesc == NULL) {
659            return effect;
660            if (status != NULL) {
661                *status = BAD_VALUE;
662            }
663        }
664
665        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
666        data.write(pDesc, sizeof(effect_descriptor_t));
667        data.writeStrongBinder(client->asBinder());
668        data.writeInt32(priority);
669        data.writeInt32((int32_t) output);
670        data.writeInt32(sessionId);
671
672        status_t lStatus = remote()->transact(CREATE_EFFECT, data, &reply);
673        if (lStatus != NO_ERROR) {
674            ALOGE("createEffect error: %s", strerror(-lStatus));
675        } else {
676            lStatus = reply.readInt32();
677            int tmp = reply.readInt32();
678            if (id != NULL) {
679                *id = tmp;
680            }
681            tmp = reply.readInt32();
682            if (enabled != NULL) {
683                *enabled = tmp;
684            }
685            effect = interface_cast<IEffect>(reply.readStrongBinder());
686            reply.read(pDesc, sizeof(effect_descriptor_t));
687        }
688        if (status != NULL) {
689            *status = lStatus;
690        }
691
692        return effect;
693    }
694
695    virtual status_t moveEffects(int session, audio_io_handle_t srcOutput,
696            audio_io_handle_t dstOutput)
697    {
698        Parcel data, reply;
699        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
700        data.writeInt32(session);
701        data.writeInt32((int32_t) srcOutput);
702        data.writeInt32((int32_t) dstOutput);
703        remote()->transact(MOVE_EFFECTS, data, &reply);
704        return reply.readInt32();
705    }
706
707    virtual audio_module_handle_t loadHwModule(const char *name)
708    {
709        Parcel data, reply;
710        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
711        data.writeCString(name);
712        remote()->transact(LOAD_HW_MODULE, data, &reply);
713        return (audio_module_handle_t) reply.readInt32();
714    }
715
716    virtual uint32_t getPrimaryOutputSamplingRate()
717    {
718        Parcel data, reply;
719        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
720        remote()->transact(GET_PRIMARY_OUTPUT_SAMPLING_RATE, data, &reply);
721        return reply.readInt32();
722    }
723
724    virtual size_t getPrimaryOutputFrameCount()
725    {
726        Parcel data, reply;
727        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
728        remote()->transact(GET_PRIMARY_OUTPUT_FRAME_COUNT, data, &reply);
729        return reply.readInt32();
730    }
731
732    virtual status_t setLowRamDevice(bool isLowRamDevice)
733    {
734        Parcel data, reply;
735        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
736        data.writeInt32((int) isLowRamDevice);
737        remote()->transact(SET_LOW_RAM_DEVICE, data, &reply);
738        return reply.readInt32();
739    }
740
741};
742
743IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
744
745// ----------------------------------------------------------------------
746
747status_t BnAudioFlinger::onTransact(
748    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
749{
750    switch (code) {
751        case CREATE_TRACK: {
752            CHECK_INTERFACE(IAudioFlinger, data, reply);
753            int streamType = data.readInt32();
754            uint32_t sampleRate = data.readInt32();
755            audio_format_t format = (audio_format_t) data.readInt32();
756            audio_channel_mask_t channelMask = data.readInt32();
757            size_t frameCount = data.readInt32();
758            track_flags_t flags = (track_flags_t) data.readInt32();
759            sp<IMemory> buffer = interface_cast<IMemory>(data.readStrongBinder());
760            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
761            pid_t tid = (pid_t) data.readInt32();
762            int sessionId = data.readInt32();
763            String8 name;
764            status_t status;
765            sp<IAudioTrack> track = createTrack(
766                    (audio_stream_type_t) streamType, sampleRate, format,
767                    channelMask, frameCount, &flags, buffer, output, tid, &sessionId, name, &status);
768            reply->writeInt32(flags);
769            reply->writeInt32(sessionId);
770            reply->writeString8(name);
771            reply->writeInt32(status);
772            reply->writeStrongBinder(track->asBinder());
773            return NO_ERROR;
774        } break;
775        case OPEN_RECORD: {
776            CHECK_INTERFACE(IAudioFlinger, data, reply);
777            audio_io_handle_t input = (audio_io_handle_t) data.readInt32();
778            uint32_t sampleRate = data.readInt32();
779            audio_format_t format = (audio_format_t) data.readInt32();
780            audio_channel_mask_t channelMask = data.readInt32();
781            size_t frameCount = data.readInt32();
782            track_flags_t flags = (track_flags_t) data.readInt32();
783            pid_t tid = (pid_t) data.readInt32();
784            int sessionId = data.readInt32();
785            status_t status;
786            sp<IAudioRecord> record = openRecord(input,
787                    sampleRate, format, channelMask, frameCount, &flags, tid, &sessionId, &status);
788            reply->writeInt32(flags);
789            reply->writeInt32(sessionId);
790            reply->writeInt32(status);
791            reply->writeStrongBinder(record->asBinder());
792            return NO_ERROR;
793        } break;
794        case SAMPLE_RATE: {
795            CHECK_INTERFACE(IAudioFlinger, data, reply);
796            reply->writeInt32( sampleRate((audio_io_handle_t) data.readInt32()) );
797            return NO_ERROR;
798        } break;
799        case FORMAT: {
800            CHECK_INTERFACE(IAudioFlinger, data, reply);
801            reply->writeInt32( format((audio_io_handle_t) data.readInt32()) );
802            return NO_ERROR;
803        } break;
804        case FRAME_COUNT: {
805            CHECK_INTERFACE(IAudioFlinger, data, reply);
806            reply->writeInt32( frameCount((audio_io_handle_t) data.readInt32()) );
807            return NO_ERROR;
808        } break;
809        case LATENCY: {
810            CHECK_INTERFACE(IAudioFlinger, data, reply);
811            reply->writeInt32( latency((audio_io_handle_t) data.readInt32()) );
812            return NO_ERROR;
813        } break;
814        case SET_MASTER_VOLUME: {
815            CHECK_INTERFACE(IAudioFlinger, data, reply);
816            reply->writeInt32( setMasterVolume(data.readFloat()) );
817            return NO_ERROR;
818        } break;
819        case SET_MASTER_MUTE: {
820            CHECK_INTERFACE(IAudioFlinger, data, reply);
821            reply->writeInt32( setMasterMute(data.readInt32()) );
822            return NO_ERROR;
823        } break;
824        case MASTER_VOLUME: {
825            CHECK_INTERFACE(IAudioFlinger, data, reply);
826            reply->writeFloat( masterVolume() );
827            return NO_ERROR;
828        } break;
829        case MASTER_MUTE: {
830            CHECK_INTERFACE(IAudioFlinger, data, reply);
831            reply->writeInt32( masterMute() );
832            return NO_ERROR;
833        } break;
834        case SET_STREAM_VOLUME: {
835            CHECK_INTERFACE(IAudioFlinger, data, reply);
836            int stream = data.readInt32();
837            float volume = data.readFloat();
838            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
839            reply->writeInt32( setStreamVolume((audio_stream_type_t) stream, volume, output) );
840            return NO_ERROR;
841        } break;
842        case SET_STREAM_MUTE: {
843            CHECK_INTERFACE(IAudioFlinger, data, reply);
844            int stream = data.readInt32();
845            reply->writeInt32( setStreamMute((audio_stream_type_t) stream, data.readInt32()) );
846            return NO_ERROR;
847        } break;
848        case STREAM_VOLUME: {
849            CHECK_INTERFACE(IAudioFlinger, data, reply);
850            int stream = data.readInt32();
851            int output = data.readInt32();
852            reply->writeFloat( streamVolume((audio_stream_type_t) stream, output) );
853            return NO_ERROR;
854        } break;
855        case STREAM_MUTE: {
856            CHECK_INTERFACE(IAudioFlinger, data, reply);
857            int stream = data.readInt32();
858            reply->writeInt32( streamMute((audio_stream_type_t) stream) );
859            return NO_ERROR;
860        } break;
861        case SET_MODE: {
862            CHECK_INTERFACE(IAudioFlinger, data, reply);
863            audio_mode_t mode = (audio_mode_t) data.readInt32();
864            reply->writeInt32( setMode(mode) );
865            return NO_ERROR;
866        } break;
867        case SET_MIC_MUTE: {
868            CHECK_INTERFACE(IAudioFlinger, data, reply);
869            int state = data.readInt32();
870            reply->writeInt32( setMicMute(state) );
871            return NO_ERROR;
872        } break;
873        case GET_MIC_MUTE: {
874            CHECK_INTERFACE(IAudioFlinger, data, reply);
875            reply->writeInt32( getMicMute() );
876            return NO_ERROR;
877        } break;
878        case SET_PARAMETERS: {
879            CHECK_INTERFACE(IAudioFlinger, data, reply);
880            audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32();
881            String8 keyValuePairs(data.readString8());
882            reply->writeInt32(setParameters(ioHandle, keyValuePairs));
883            return NO_ERROR;
884        } break;
885        case GET_PARAMETERS: {
886            CHECK_INTERFACE(IAudioFlinger, data, reply);
887            audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32();
888            String8 keys(data.readString8());
889            reply->writeString8(getParameters(ioHandle, keys));
890            return NO_ERROR;
891        } break;
892
893        case REGISTER_CLIENT: {
894            CHECK_INTERFACE(IAudioFlinger, data, reply);
895            sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient>(
896                    data.readStrongBinder());
897            registerClient(client);
898            return NO_ERROR;
899        } break;
900        case GET_INPUTBUFFERSIZE: {
901            CHECK_INTERFACE(IAudioFlinger, data, reply);
902            uint32_t sampleRate = data.readInt32();
903            audio_format_t format = (audio_format_t) data.readInt32();
904            audio_channel_mask_t channelMask = data.readInt32();
905            reply->writeInt32( getInputBufferSize(sampleRate, format, channelMask) );
906            return NO_ERROR;
907        } break;
908        case OPEN_OUTPUT: {
909            CHECK_INTERFACE(IAudioFlinger, data, reply);
910            audio_module_handle_t module = (audio_module_handle_t)data.readInt32();
911            audio_devices_t devices = (audio_devices_t)data.readInt32();
912            uint32_t samplingRate = data.readInt32();
913            audio_format_t format = (audio_format_t) data.readInt32();
914            audio_channel_mask_t channelMask = (audio_channel_mask_t)data.readInt32();
915            uint32_t latency = data.readInt32();
916            audio_output_flags_t flags = (audio_output_flags_t) data.readInt32();
917            bool hasOffloadInfo = data.readInt32() != 0;
918            audio_offload_info_t offloadInfo;
919            if (hasOffloadInfo) {
920                data.read(&offloadInfo, sizeof(audio_offload_info_t));
921            }
922            audio_io_handle_t output = openOutput(module,
923                                                 &devices,
924                                                 &samplingRate,
925                                                 &format,
926                                                 &channelMask,
927                                                 &latency,
928                                                 flags,
929                                                 hasOffloadInfo ? &offloadInfo : NULL);
930            ALOGV("OPEN_OUTPUT output, %p", output);
931            reply->writeInt32((int32_t) output);
932            reply->writeInt32(devices);
933            reply->writeInt32(samplingRate);
934            reply->writeInt32(format);
935            reply->writeInt32(channelMask);
936            reply->writeInt32(latency);
937            return NO_ERROR;
938        } break;
939        case OPEN_DUPLICATE_OUTPUT: {
940            CHECK_INTERFACE(IAudioFlinger, data, reply);
941            audio_io_handle_t output1 = (audio_io_handle_t) data.readInt32();
942            audio_io_handle_t output2 = (audio_io_handle_t) data.readInt32();
943            reply->writeInt32((int32_t) openDuplicateOutput(output1, output2));
944            return NO_ERROR;
945        } break;
946        case CLOSE_OUTPUT: {
947            CHECK_INTERFACE(IAudioFlinger, data, reply);
948            reply->writeInt32(closeOutput((audio_io_handle_t) data.readInt32()));
949            return NO_ERROR;
950        } break;
951        case SUSPEND_OUTPUT: {
952            CHECK_INTERFACE(IAudioFlinger, data, reply);
953            reply->writeInt32(suspendOutput((audio_io_handle_t) data.readInt32()));
954            return NO_ERROR;
955        } break;
956        case RESTORE_OUTPUT: {
957            CHECK_INTERFACE(IAudioFlinger, data, reply);
958            reply->writeInt32(restoreOutput((audio_io_handle_t) data.readInt32()));
959            return NO_ERROR;
960        } break;
961        case OPEN_INPUT: {
962            CHECK_INTERFACE(IAudioFlinger, data, reply);
963            audio_module_handle_t module = (audio_module_handle_t)data.readInt32();
964            audio_devices_t devices = (audio_devices_t)data.readInt32();
965            uint32_t samplingRate = data.readInt32();
966            audio_format_t format = (audio_format_t) data.readInt32();
967            audio_channel_mask_t channelMask = (audio_channel_mask_t)data.readInt32();
968
969            audio_io_handle_t input = openInput(module,
970                                             &devices,
971                                             &samplingRate,
972                                             &format,
973                                             &channelMask);
974            reply->writeInt32((int32_t) input);
975            reply->writeInt32(devices);
976            reply->writeInt32(samplingRate);
977            reply->writeInt32(format);
978            reply->writeInt32(channelMask);
979            return NO_ERROR;
980        } break;
981        case CLOSE_INPUT: {
982            CHECK_INTERFACE(IAudioFlinger, data, reply);
983            reply->writeInt32(closeInput((audio_io_handle_t) data.readInt32()));
984            return NO_ERROR;
985        } break;
986        case SET_STREAM_OUTPUT: {
987            CHECK_INTERFACE(IAudioFlinger, data, reply);
988            uint32_t stream = data.readInt32();
989            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
990            reply->writeInt32(setStreamOutput((audio_stream_type_t) stream, output));
991            return NO_ERROR;
992        } break;
993        case SET_VOICE_VOLUME: {
994            CHECK_INTERFACE(IAudioFlinger, data, reply);
995            float volume = data.readFloat();
996            reply->writeInt32( setVoiceVolume(volume) );
997            return NO_ERROR;
998        } break;
999        case GET_RENDER_POSITION: {
1000            CHECK_INTERFACE(IAudioFlinger, data, reply);
1001            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
1002            size_t halFrames;
1003            size_t dspFrames;
1004            status_t status = getRenderPosition(&halFrames, &dspFrames, output);
1005            reply->writeInt32(status);
1006            if (status == NO_ERROR) {
1007                reply->writeInt32(halFrames);
1008                reply->writeInt32(dspFrames);
1009            }
1010            return NO_ERROR;
1011        }
1012        case GET_INPUT_FRAMES_LOST: {
1013            CHECK_INTERFACE(IAudioFlinger, data, reply);
1014            audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32();
1015            reply->writeInt32(getInputFramesLost(ioHandle));
1016            return NO_ERROR;
1017        } break;
1018        case NEW_AUDIO_SESSION_ID: {
1019            CHECK_INTERFACE(IAudioFlinger, data, reply);
1020            reply->writeInt32(newAudioSessionId());
1021            return NO_ERROR;
1022        } break;
1023        case ACQUIRE_AUDIO_SESSION_ID: {
1024            CHECK_INTERFACE(IAudioFlinger, data, reply);
1025            int audioSession = data.readInt32();
1026            acquireAudioSessionId(audioSession);
1027            return NO_ERROR;
1028        } break;
1029        case RELEASE_AUDIO_SESSION_ID: {
1030            CHECK_INTERFACE(IAudioFlinger, data, reply);
1031            int audioSession = data.readInt32();
1032            releaseAudioSessionId(audioSession);
1033            return NO_ERROR;
1034        } break;
1035        case QUERY_NUM_EFFECTS: {
1036            CHECK_INTERFACE(IAudioFlinger, data, reply);
1037            uint32_t numEffects;
1038            status_t status = queryNumberEffects(&numEffects);
1039            reply->writeInt32(status);
1040            if (status == NO_ERROR) {
1041                reply->writeInt32((int32_t)numEffects);
1042            }
1043            return NO_ERROR;
1044        }
1045        case QUERY_EFFECT: {
1046            CHECK_INTERFACE(IAudioFlinger, data, reply);
1047            effect_descriptor_t desc;
1048            status_t status = queryEffect(data.readInt32(), &desc);
1049            reply->writeInt32(status);
1050            if (status == NO_ERROR) {
1051                reply->write(&desc, sizeof(effect_descriptor_t));
1052            }
1053            return NO_ERROR;
1054        }
1055        case GET_EFFECT_DESCRIPTOR: {
1056            CHECK_INTERFACE(IAudioFlinger, data, reply);
1057            effect_uuid_t uuid;
1058            data.read(&uuid, sizeof(effect_uuid_t));
1059            effect_descriptor_t desc;
1060            status_t status = getEffectDescriptor(&uuid, &desc);
1061            reply->writeInt32(status);
1062            if (status == NO_ERROR) {
1063                reply->write(&desc, sizeof(effect_descriptor_t));
1064            }
1065            return NO_ERROR;
1066        }
1067        case CREATE_EFFECT: {
1068            CHECK_INTERFACE(IAudioFlinger, data, reply);
1069            effect_descriptor_t desc;
1070            data.read(&desc, sizeof(effect_descriptor_t));
1071            sp<IEffectClient> client = interface_cast<IEffectClient>(data.readStrongBinder());
1072            int32_t priority = data.readInt32();
1073            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
1074            int sessionId = data.readInt32();
1075            status_t status;
1076            int id;
1077            int enabled;
1078
1079            sp<IEffect> effect = createEffect(&desc, client, priority, output, sessionId,
1080                    &status, &id, &enabled);
1081            reply->writeInt32(status);
1082            reply->writeInt32(id);
1083            reply->writeInt32(enabled);
1084            reply->writeStrongBinder(effect->asBinder());
1085            reply->write(&desc, sizeof(effect_descriptor_t));
1086            return NO_ERROR;
1087        } break;
1088        case MOVE_EFFECTS: {
1089            CHECK_INTERFACE(IAudioFlinger, data, reply);
1090            int session = data.readInt32();
1091            audio_io_handle_t srcOutput = (audio_io_handle_t) data.readInt32();
1092            audio_io_handle_t dstOutput = (audio_io_handle_t) data.readInt32();
1093            reply->writeInt32(moveEffects(session, srcOutput, dstOutput));
1094            return NO_ERROR;
1095        } break;
1096        case LOAD_HW_MODULE: {
1097            CHECK_INTERFACE(IAudioFlinger, data, reply);
1098            reply->writeInt32(loadHwModule(data.readCString()));
1099            return NO_ERROR;
1100        } break;
1101        case GET_PRIMARY_OUTPUT_SAMPLING_RATE: {
1102            CHECK_INTERFACE(IAudioFlinger, data, reply);
1103            reply->writeInt32(getPrimaryOutputSamplingRate());
1104            return NO_ERROR;
1105        } break;
1106        case GET_PRIMARY_OUTPUT_FRAME_COUNT: {
1107            CHECK_INTERFACE(IAudioFlinger, data, reply);
1108            reply->writeInt32(getPrimaryOutputFrameCount());
1109            return NO_ERROR;
1110        } break;
1111        case SET_LOW_RAM_DEVICE: {
1112            CHECK_INTERFACE(IAudioFlinger, data, reply);
1113            bool isLowRamDevice = data.readInt32() != 0;
1114            reply->writeInt32(setLowRamDevice(isLowRamDevice));
1115            return NO_ERROR;
1116        } break;
1117        default:
1118            return BBinder::onTransact(code, data, reply, flags);
1119    }
1120}
1121
1122// ----------------------------------------------------------------------------
1123
1124}; // namespace android
1125