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