IAudioFlinger.cpp revision 5e07b5774c8b376776caa4f5b0a193767697e97e
1/* //device/extlibs/pv/android/IAudioflinger.cpp
2**
3** Copyright 2007, The Android Open Source Project
4**
5** Licensed under the Apache License, Version 2.0 (the "License");
6** you may not use this file except in compliance with the License.
7** You may obtain a copy of the License at
8**
9**     http://www.apache.org/licenses/LICENSE-2.0
10**
11** Unless required by applicable law or agreed to in writing, software
12** distributed under the License is distributed on an "AS IS" BASIS,
13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14** See the License for the specific language governing permissions and
15** limitations under the License.
16*/
17
18#define LOG_TAG "IAudioFlinger"
19#include <utils/Log.h>
20
21#include <stdint.h>
22#include <sys/types.h>
23
24#include <utils/Parcel.h>
25
26#include <media/IAudioFlinger.h>
27
28namespace android {
29
30enum {
31    CREATE_TRACK = IBinder::FIRST_CALL_TRANSACTION,
32    OPEN_RECORD,
33    SAMPLE_RATE,
34    CHANNEL_COUNT,
35    FORMAT,
36    FRAME_COUNT,
37    LATENCY,
38    SET_MASTER_VOLUME,
39    SET_MASTER_MUTE,
40    MASTER_VOLUME,
41    MASTER_MUTE,
42    SET_STREAM_VOLUME,
43    SET_STREAM_MUTE,
44    STREAM_VOLUME,
45    STREAM_MUTE,
46    SET_MODE,
47    GET_MODE,
48    SET_ROUTING,
49    GET_ROUTING,
50    SET_MIC_MUTE,
51    GET_MIC_MUTE,
52    IS_MUSIC_ACTIVE,
53    SET_PARAMETER,
54    REGISTER_CLIENT,
55    GET_INPUTBUFFERSIZE,
56    WAKE_UP
57};
58
59class BpAudioFlinger : public BpInterface<IAudioFlinger>
60{
61public:
62    BpAudioFlinger(const sp<IBinder>& impl)
63        : BpInterface<IAudioFlinger>(impl)
64    {
65    }
66
67    virtual sp<IAudioTrack> createTrack(
68                                pid_t pid,
69                                int streamType,
70                                uint32_t sampleRate,
71                                int format,
72                                int channelCount,
73                                int frameCount,
74                                uint32_t flags,
75                                const sp<IMemory>& sharedBuffer,
76                                status_t *status)
77    {
78        Parcel data, reply;
79        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
80        data.writeInt32(pid);
81        data.writeInt32(streamType);
82        data.writeInt32(sampleRate);
83        data.writeInt32(format);
84        data.writeInt32(channelCount);
85        data.writeInt32(frameCount);
86        data.writeInt32(flags);
87        data.writeStrongBinder(sharedBuffer->asBinder());
88        status_t lStatus = remote()->transact(CREATE_TRACK, data, &reply);
89        if (lStatus != NO_ERROR) {
90            LOGE("createTrack error: %s", strerror(-lStatus));
91        }
92        lStatus = reply.readInt32();
93        if (status) {
94            *status = lStatus;
95        }
96        return interface_cast<IAudioTrack>(reply.readStrongBinder());
97    }
98
99    virtual sp<IAudioRecord> openRecord(
100                                pid_t pid,
101                                int streamType,
102                                uint32_t sampleRate,
103                                int format,
104                                int channelCount,
105                                int frameCount,
106                                uint32_t flags,
107                                status_t *status)
108    {
109        Parcel data, reply;
110        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
111        data.writeInt32(pid);
112        data.writeInt32(streamType);
113        data.writeInt32(sampleRate);
114        data.writeInt32(format);
115        data.writeInt32(channelCount);
116        data.writeInt32(frameCount);
117        data.writeInt32(flags);
118        remote()->transact(OPEN_RECORD, data, &reply);
119        status_t lStatus = reply.readInt32();
120        if (status) {
121            *status = lStatus;
122        }
123        return interface_cast<IAudioRecord>(reply.readStrongBinder());
124    }
125
126    virtual uint32_t sampleRate() const
127    {
128        Parcel data, reply;
129        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
130        remote()->transact(SAMPLE_RATE, data, &reply);
131        return reply.readInt32();
132    }
133
134    virtual int channelCount() const
135    {
136        Parcel data, reply;
137        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
138        remote()->transact(CHANNEL_COUNT, data, &reply);
139        return reply.readInt32();
140    }
141
142    virtual int format() const
143    {
144        Parcel data, reply;
145        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
146        remote()->transact(FORMAT, data, &reply);
147        return reply.readInt32();
148    }
149
150    virtual size_t frameCount() const
151    {
152        Parcel data, reply;
153        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
154        remote()->transact(FRAME_COUNT, data, &reply);
155        return reply.readInt32();
156    }
157
158    virtual uint32_t latency() const
159    {
160        Parcel data, reply;
161        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
162        remote()->transact(LATENCY, data, &reply);
163        return reply.readInt32();
164    }
165
166    virtual status_t setMasterVolume(float value)
167    {
168        Parcel data, reply;
169        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
170        data.writeFloat(value);
171        remote()->transact(SET_MASTER_VOLUME, data, &reply);
172        return reply.readInt32();
173    }
174
175    virtual status_t setMasterMute(bool muted)
176    {
177        Parcel data, reply;
178        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
179        data.writeInt32(muted);
180        remote()->transact(SET_MASTER_MUTE, data, &reply);
181        return reply.readInt32();
182    }
183
184    virtual float masterVolume() const
185    {
186        Parcel data, reply;
187        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
188        remote()->transact(MASTER_VOLUME, data, &reply);
189        return reply.readFloat();
190    }
191
192    virtual bool masterMute() const
193    {
194        Parcel data, reply;
195        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
196        remote()->transact(MASTER_MUTE, data, &reply);
197        return reply.readInt32();
198    }
199
200    virtual status_t setStreamVolume(int stream, float value)
201    {
202        Parcel data, reply;
203        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
204        data.writeInt32(stream);
205        data.writeFloat(value);
206        remote()->transact(SET_STREAM_VOLUME, data, &reply);
207        return reply.readInt32();
208    }
209
210    virtual status_t setStreamMute(int stream, bool muted)
211    {
212        Parcel data, reply;
213        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
214        data.writeInt32(stream);
215        data.writeInt32(muted);
216        remote()->transact(SET_STREAM_MUTE, data, &reply);
217        return reply.readInt32();
218    }
219
220    virtual float streamVolume(int stream) const
221    {
222        Parcel data, reply;
223        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
224        data.writeInt32(stream);
225        remote()->transact(STREAM_VOLUME, data, &reply);
226        return reply.readFloat();
227    }
228
229    virtual bool streamMute(int stream) const
230    {
231        Parcel data, reply;
232        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
233        data.writeInt32(stream);
234        remote()->transact(STREAM_MUTE, data, &reply);
235        return reply.readInt32();
236    }
237
238    virtual status_t setRouting(int mode, uint32_t routes, uint32_t mask)
239    {
240        Parcel data, reply;
241        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
242        data.writeInt32(mode);
243        data.writeInt32(routes);
244        data.writeInt32(mask);
245        remote()->transact(SET_ROUTING, data, &reply);
246        return reply.readInt32();
247    }
248
249    virtual uint32_t getRouting(int mode) const
250    {
251        Parcel data, reply;
252        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
253        data.writeInt32(mode);
254        remote()->transact(GET_ROUTING, data, &reply);
255        return reply.readInt32();
256    }
257
258    virtual status_t setMode(int mode)
259    {
260        Parcel data, reply;
261        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
262        data.writeInt32(mode);
263        remote()->transact(SET_MODE, data, &reply);
264        return reply.readInt32();
265    }
266
267    virtual int getMode() const
268    {
269        Parcel data, reply;
270        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
271        remote()->transact(GET_MODE, data, &reply);
272        return reply.readInt32();
273    }
274
275    virtual status_t setMicMute(bool state)
276    {
277        Parcel data, reply;
278        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
279        data.writeInt32(state);
280        remote()->transact(SET_MIC_MUTE, data, &reply);
281        return reply.readInt32();
282    }
283
284    virtual bool getMicMute() const
285    {
286        Parcel data, reply;
287        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
288        remote()->transact(GET_MIC_MUTE, data, &reply);
289        return reply.readInt32();
290    }
291
292    virtual bool isMusicActive() const
293    {
294        Parcel data, reply;
295        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
296        remote()->transact(IS_MUSIC_ACTIVE, data, &reply);
297        return reply.readInt32();
298    }
299
300    virtual status_t setParameter(const char* key, const char* value)
301    {
302        Parcel data, reply;
303        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
304        data.writeCString(key);
305        data.writeCString(value);
306        remote()->transact(SET_PARAMETER, data, &reply);
307        return reply.readInt32();
308    }
309
310    virtual void registerClient(const sp<IAudioFlingerClient>& client)
311    {
312        Parcel data, reply;
313        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
314        data.writeStrongBinder(client->asBinder());
315        remote()->transact(REGISTER_CLIENT, data, &reply);
316    }
317
318    virtual size_t getInputBufferSize(uint32_t sampleRate, int format, int channelCount)
319    {
320        Parcel data, reply;
321        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
322        data.writeInt32(sampleRate);
323        data.writeInt32(format);
324        data.writeInt32(channelCount);
325        remote()->transact(GET_INPUTBUFFERSIZE, data, &reply);
326        return reply.readInt32();
327    }
328
329    virtual void wakeUp()
330    {
331        Parcel data, reply;
332        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
333        remote()->transact(WAKE_UP, data, &reply);
334        return;
335    }
336};
337
338IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
339
340// ----------------------------------------------------------------------
341
342#define CHECK_INTERFACE(interface, data, reply) \
343        do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
344            LOGW("Call incorrectly routed to " #interface); \
345            return PERMISSION_DENIED; \
346        } } while (0)
347
348status_t BnAudioFlinger::onTransact(
349    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
350{
351    switch(code) {
352        case CREATE_TRACK: {
353            CHECK_INTERFACE(IAudioFlinger, data, reply);
354            pid_t pid = data.readInt32();
355            int streamType = data.readInt32();
356            uint32_t sampleRate = data.readInt32();
357            int format = data.readInt32();
358            int channelCount = data.readInt32();
359            size_t bufferCount = data.readInt32();
360            uint32_t flags = data.readInt32();
361            sp<IMemory> buffer = interface_cast<IMemory>(data.readStrongBinder());
362            status_t status;
363            sp<IAudioTrack> track = createTrack(pid,
364                    streamType, sampleRate, format,
365                    channelCount, bufferCount, flags, buffer, &status);
366            reply->writeInt32(status);
367            reply->writeStrongBinder(track->asBinder());
368            return NO_ERROR;
369        } break;
370        case OPEN_RECORD: {
371            CHECK_INTERFACE(IAudioFlinger, data, reply);
372            pid_t pid = data.readInt32();
373            int streamType = data.readInt32();
374            uint32_t sampleRate = data.readInt32();
375            int format = data.readInt32();
376            int channelCount = data.readInt32();
377            size_t bufferCount = data.readInt32();
378            uint32_t flags = data.readInt32();
379            status_t status;
380            sp<IAudioRecord> record = openRecord(pid, streamType,
381                    sampleRate, format, channelCount, bufferCount, flags, &status);
382            reply->writeInt32(status);
383            reply->writeStrongBinder(record->asBinder());
384            return NO_ERROR;
385        } break;
386        case SAMPLE_RATE: {
387            CHECK_INTERFACE(IAudioFlinger, data, reply);
388            reply->writeInt32( sampleRate() );
389            return NO_ERROR;
390        } break;
391        case CHANNEL_COUNT: {
392            CHECK_INTERFACE(IAudioFlinger, data, reply);
393            reply->writeInt32( channelCount() );
394            return NO_ERROR;
395        } break;
396        case FORMAT: {
397            CHECK_INTERFACE(IAudioFlinger, data, reply);
398            reply->writeInt32( format() );
399            return NO_ERROR;
400        } break;
401        case FRAME_COUNT: {
402            CHECK_INTERFACE(IAudioFlinger, data, reply);
403            reply->writeInt32( frameCount() );
404            return NO_ERROR;
405        } break;
406        case LATENCY: {
407            CHECK_INTERFACE(IAudioFlinger, data, reply);
408            reply->writeInt32( latency() );
409            return NO_ERROR;
410        } break;
411         case SET_MASTER_VOLUME: {
412            CHECK_INTERFACE(IAudioFlinger, data, reply);
413            reply->writeInt32( setMasterVolume(data.readFloat()) );
414            return NO_ERROR;
415        } break;
416        case SET_MASTER_MUTE: {
417            CHECK_INTERFACE(IAudioFlinger, data, reply);
418            reply->writeInt32( setMasterMute(data.readInt32()) );
419            return NO_ERROR;
420        } break;
421        case MASTER_VOLUME: {
422            CHECK_INTERFACE(IAudioFlinger, data, reply);
423            reply->writeFloat( masterVolume() );
424            return NO_ERROR;
425        } break;
426        case MASTER_MUTE: {
427            CHECK_INTERFACE(IAudioFlinger, data, reply);
428            reply->writeInt32( masterMute() );
429            return NO_ERROR;
430        } break;
431        case SET_STREAM_VOLUME: {
432            CHECK_INTERFACE(IAudioFlinger, data, reply);
433            int stream = data.readInt32();
434            reply->writeInt32( setStreamVolume(stream, data.readFloat()) );
435            return NO_ERROR;
436        } break;
437        case SET_STREAM_MUTE: {
438            CHECK_INTERFACE(IAudioFlinger, data, reply);
439            int stream = data.readInt32();
440            reply->writeInt32( setStreamMute(stream, data.readInt32()) );
441            return NO_ERROR;
442        } break;
443        case STREAM_VOLUME: {
444            CHECK_INTERFACE(IAudioFlinger, data, reply);
445            int stream = data.readInt32();
446            reply->writeFloat( streamVolume(stream) );
447            return NO_ERROR;
448        } break;
449        case STREAM_MUTE: {
450            CHECK_INTERFACE(IAudioFlinger, data, reply);
451            int stream = data.readInt32();
452            reply->writeInt32( streamMute(stream) );
453            return NO_ERROR;
454        } break;
455        case SET_ROUTING: {
456            CHECK_INTERFACE(IAudioFlinger, data, reply);
457            int mode = data.readInt32();
458            uint32_t routes = data.readInt32();
459            uint32_t mask = data.readInt32();
460            reply->writeInt32( setRouting(mode, routes, mask) );
461            return NO_ERROR;
462        } break;
463        case GET_ROUTING: {
464            CHECK_INTERFACE(IAudioFlinger, data, reply);
465            int mode = data.readInt32();
466            reply->writeInt32( getRouting(mode) );
467            return NO_ERROR;
468        } break;
469        case SET_MODE: {
470            CHECK_INTERFACE(IAudioFlinger, data, reply);
471            int mode = data.readInt32();
472            reply->writeInt32( setMode(mode) );
473            return NO_ERROR;
474        } break;
475        case GET_MODE: {
476            CHECK_INTERFACE(IAudioFlinger, data, reply);
477            reply->writeInt32( getMode() );
478            return NO_ERROR;
479        } break;
480        case SET_MIC_MUTE: {
481            CHECK_INTERFACE(IAudioFlinger, data, reply);
482            int state = data.readInt32();
483            reply->writeInt32( setMicMute(state) );
484            return NO_ERROR;
485        } break;
486        case GET_MIC_MUTE: {
487            CHECK_INTERFACE(IAudioFlinger, data, reply);
488            reply->writeInt32( getMicMute() );
489            return NO_ERROR;
490        } break;
491        case IS_MUSIC_ACTIVE: {
492            CHECK_INTERFACE(IAudioFlinger, data, reply);
493            reply->writeInt32( isMusicActive() );
494            return NO_ERROR;
495        } break;
496        case SET_PARAMETER: {
497            CHECK_INTERFACE(IAudioFlinger, data, reply);
498            const char *key = data.readCString();
499            const char *value = data.readCString();
500            reply->writeInt32( setParameter(key, value) );
501            return NO_ERROR;
502        } break;
503        case REGISTER_CLIENT: {
504            CHECK_INTERFACE(IAudioFlinger, data, reply);
505            sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient>(data.readStrongBinder());
506            registerClient(client);
507            return NO_ERROR;
508        } break;
509        case GET_INPUTBUFFERSIZE: {
510            CHECK_INTERFACE(IAudioFlinger, data, reply);
511            uint32_t sampleRate = data.readInt32();
512            int format = data.readInt32();
513            int channelCount = data.readInt32();
514            reply->writeInt32( getInputBufferSize(sampleRate, format, channelCount) );
515            return NO_ERROR;
516        } break;
517        case WAKE_UP: {
518            CHECK_INTERFACE(IAudioFlinger, data, reply);
519            wakeUp();
520            return NO_ERROR;
521        } break;
522
523        default:
524            return BBinder::onTransact(code, data, reply, flags);
525    }
526}
527
528// ----------------------------------------------------------------------------
529
530}; // namespace android
531