IAudioFlinger.cpp revision de3f8392fbf380ba6f09d009b00d7172477389a2
15778822d86b0337407514b9372562b86edfa91cdAndreas Huber/*
25778822d86b0337407514b9372562b86edfa91cdAndreas Huber**
35778822d86b0337407514b9372562b86edfa91cdAndreas Huber** Copyright 2007, The Android Open Source Project
45778822d86b0337407514b9372562b86edfa91cdAndreas Huber**
55778822d86b0337407514b9372562b86edfa91cdAndreas Huber** Licensed under the Apache License, Version 2.0 (the "License");
65778822d86b0337407514b9372562b86edfa91cdAndreas Huber** you may not use this file except in compliance with the License.
75778822d86b0337407514b9372562b86edfa91cdAndreas Huber** You may obtain a copy of the License at
85778822d86b0337407514b9372562b86edfa91cdAndreas Huber**
95778822d86b0337407514b9372562b86edfa91cdAndreas Huber**     http://www.apache.org/licenses/LICENSE-2.0
105778822d86b0337407514b9372562b86edfa91cdAndreas Huber**
115778822d86b0337407514b9372562b86edfa91cdAndreas Huber** Unless required by applicable law or agreed to in writing, software
125778822d86b0337407514b9372562b86edfa91cdAndreas Huber** distributed under the License is distributed on an "AS IS" BASIS,
135778822d86b0337407514b9372562b86edfa91cdAndreas Huber** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
145778822d86b0337407514b9372562b86edfa91cdAndreas Huber** See the License for the specific language governing permissions and
155778822d86b0337407514b9372562b86edfa91cdAndreas Huber** limitations under the License.
165778822d86b0337407514b9372562b86edfa91cdAndreas Huber*/
175778822d86b0337407514b9372562b86edfa91cdAndreas Huber
185778822d86b0337407514b9372562b86edfa91cdAndreas Huber#define LOG_TAG "IAudioFlinger"
195778822d86b0337407514b9372562b86edfa91cdAndreas Huber//#define LOG_NDEBUG 0
205778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <utils/Log.h>
218ba01021b573889802e67e029225a96f0dfa471aAndy McFadden
224b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber#include <stdint.h>
235b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar#include <sys/types.h>
2467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
255778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <binder/Parcel.h>
2690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar
275778822d86b0337407514b9372562b86edfa91cdAndreas Huber#include <media/IAudioFlinger.h>
285778822d86b0337407514b9372562b86edfa91cdAndreas Huber
295778822d86b0337407514b9372562b86edfa91cdAndreas Hubernamespace android {
305778822d86b0337407514b9372562b86edfa91cdAndreas Huber
315778822d86b0337407514b9372562b86edfa91cdAndreas Huberenum {
325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CREATE_TRACK = IBinder::FIRST_CALL_TRANSACTION,
333f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar    OPEN_RECORD,
345b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber    SAMPLE_RATE,
3592cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar    RESERVED,   // obsolete, was CHANNEL_COUNT
362606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    FORMAT,
37c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker    FRAME_COUNT,
38ee4e1b1a63758941460ae79a064249d3a5189443Lajos Molnar    LATENCY,
39c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker    SET_MASTER_VOLUME,
4067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    SET_MASTER_MUTE,
4167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    MASTER_VOLUME,
42d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    MASTER_MUTE,
435778822d86b0337407514b9372562b86edfa91cdAndreas Huber    SET_STREAM_VOLUME,
441a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian    SET_STREAM_MUTE,
455778822d86b0337407514b9372562b86edfa91cdAndreas Huber    STREAM_VOLUME,
465778822d86b0337407514b9372562b86edfa91cdAndreas Huber    STREAM_MUTE,
475778822d86b0337407514b9372562b86edfa91cdAndreas Huber    SET_MODE,
485778822d86b0337407514b9372562b86edfa91cdAndreas Huber    SET_MIC_MUTE,
495778822d86b0337407514b9372562b86edfa91cdAndreas Huber    GET_MIC_MUTE,
505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    SET_PARAMETERS,
515778822d86b0337407514b9372562b86edfa91cdAndreas Huber    GET_PARAMETERS,
525778822d86b0337407514b9372562b86edfa91cdAndreas Huber    REGISTER_CLIENT,
535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    GET_INPUTBUFFERSIZE,
545778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OPEN_OUTPUT,
555778822d86b0337407514b9372562b86edfa91cdAndreas Huber    OPEN_DUPLICATE_OUTPUT,
565778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CLOSE_OUTPUT,
57c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    SUSPEND_OUTPUT,
58c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    RESTORE_OUTPUT,
59c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    OPEN_INPUT,
60c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    CLOSE_INPUT,
61c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    INVALIDATE_STREAM,
6299acce4526db0f14be6e516ecb3920d5ed66877bRonghua Wu    SET_VOICE_VOLUME,
63c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    GET_RENDER_POSITION,
64c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    GET_INPUT_FRAMES_LOST,
6568845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    NEW_AUDIO_SESSION_ID,
6668845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    ACQUIRE_AUDIO_SESSION_ID,
675778822d86b0337407514b9372562b86edfa91cdAndreas Huber    RELEASE_AUDIO_SESSION_ID,
686fc17d1a7c5d2fb117491b2e9f66c6236b526508Lajos Molnar    QUERY_NUM_EFFECTS,
6968845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    QUERY_EFFECT,
705778822d86b0337407514b9372562b86edfa91cdAndreas Huber    GET_EFFECT_DESCRIPTOR,
715778822d86b0337407514b9372562b86edfa91cdAndreas Huber    CREATE_EFFECT,
726fc17d1a7c5d2fb117491b2e9f66c6236b526508Lajos Molnar    MOVE_EFFECTS,
7368845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    LOAD_HW_MODULE,
745778822d86b0337407514b9372562b86edfa91cdAndreas Huber    GET_PRIMARY_OUTPUT_SAMPLING_RATE,
75d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    GET_PRIMARY_OUTPUT_FRAME_COUNT,
76d291c222357303b9611cab89d0c3b047584ef377Chong Zhang    SET_LOW_RAM_DEVICE,
775b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    LIST_AUDIO_PORTS,
785b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    GET_AUDIO_PORT,
795b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    CREATE_AUDIO_PATCH,
805b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    RELEASE_AUDIO_PATCH,
815b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    LIST_AUDIO_PATCHES,
825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    SET_AUDIO_PORT_CONFIG
835778822d86b0337407514b9372562b86edfa91cdAndreas Huber};
841a2952aee048ca7b1765e2bc09ebe9aeddaeafa3Mathias Agopian
851bd139a2a68690e80398b70b27ca59550fea0e65Andreas Huberclass BpAudioFlinger : public BpInterface<IAudioFlinger>
865778822d86b0337407514b9372562b86edfa91cdAndreas Huber{
875778822d86b0337407514b9372562b86edfa91cdAndreas Huberpublic:
88c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    BpAudioFlinger(const sp<IBinder>& impl)
89c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        : BpInterface<IAudioFlinger>(impl)
9090fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    {
9190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    }
927cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden
937cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden    virtual sp<IAudioTrack> createTrack(
948f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang                                audio_stream_type_t streamType,
95d291c222357303b9611cab89d0c3b047584ef377Chong Zhang                                uint32_t sampleRate,
965778822d86b0337407514b9372562b86edfa91cdAndreas Huber                                audio_format_t format,
97c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                                audio_channel_mask_t channelMask,
98c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                                size_t *pFrameCount,
99c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber                                track_flags_t *flags,
1005778822d86b0337407514b9372562b86edfa91cdAndreas Huber                                const sp<IMemory>& sharedBuffer,
1015778822d86b0337407514b9372562b86edfa91cdAndreas Huber                                audio_io_handle_t output,
102671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar                                pid_t tid,
103671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar                                int *sessionId,
104671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar                                int clientUid,
105671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar                                status_t *status)
106c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber    {
107c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        Parcel data, reply;
108c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        sp<IAudioTrack> track;
109c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
1105778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeInt32((int32_t) streamType);
1115778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeInt32(sampleRate);
1125778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeInt32(format);
1135778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeInt32(channelMask);
1145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t frameCount = pFrameCount != NULL ? *pFrameCount : 0;
1155778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeInt64(frameCount);
1165778822d86b0337407514b9372562b86edfa91cdAndreas Huber        track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT;
1175b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        data.writeInt32(lFlags);
1185b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        // haveSharedBuffer
1195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (sharedBuffer != 0) {
1204b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            data.writeInt32(true);
1214b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            data.writeStrongBinder(sharedBuffer->asBinder());
1224b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        } else {
1234b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            data.writeInt32(false);
1244b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        }
1254b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        data.writeInt32((int32_t) output);
1264b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        data.writeInt32((int32_t) tid);
1274b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        int lSessionId = AUDIO_SESSION_ALLOCATE;
12818cb1eca504817b5b144a023ae2792d90e74c9a5Jeff Tinker        if (sessionId != NULL) {
1294b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber            lSessionId = *sessionId;
1305b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        }
1315b8987e7de9d04b09153f329c680d2316cdb44ecAndreas Huber        data.writeInt32(lSessionId);
1324b75a9c8b93a90749bc5d22912ad0d96c12f4ecfAndreas Huber        data.writeInt32(clientUid);
1335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t lStatus = remote()->transact(CREATE_TRACK, data, &reply);
1345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (lStatus != NO_ERROR) {
1355778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("createTrack error: %s", strerror(-lStatus));
1365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
1375778822d86b0337407514b9372562b86edfa91cdAndreas Huber            frameCount = reply.readInt64();
1385778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (pFrameCount != NULL) {
1395778822d86b0337407514b9372562b86edfa91cdAndreas Huber                *pFrameCount = frameCount;
1405778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
1415778822d86b0337407514b9372562b86edfa91cdAndreas Huber            lFlags = reply.readInt32();
1425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (flags != NULL) {
143fc7fca77caa12993dd938d5ff43797d781291027Lajos Molnar                *flags = lFlags;
1445778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
1455778822d86b0337407514b9372562b86edfa91cdAndreas Huber            lSessionId = reply.readInt32();
1465778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (sessionId != NULL) {
1477cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                *sessionId = lSessionId;
1487cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
1495778822d86b0337407514b9372562b86edfa91cdAndreas Huber            lStatus = reply.readInt32();
150e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            track = interface_cast<IAudioTrack>(reply.readStrongBinder());
1515778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (lStatus == NO_ERROR) {
152e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar                if (track == 0) {
153e6109e2f10b43c2cc2561c6fd6633b5f988bd7a9Lajos Molnar                    ALOGE("createTrack should have returned an IAudioTrack");
1545778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    lStatus = UNKNOWN_ERROR;
1555778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
1565778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
1577bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar                if (track != 0) {
1587bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar                    ALOGE("createTrack returned an IAudioTrack but with status %d", lStatus);
1597bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar                    track.clear();
1607bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar                }
1611dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            }
1621dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar        }
163496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber        if (status != NULL) {
164496238cc7551d414067dcbbb4fe3bd801f205f95Andreas Huber            *status = lStatus;
165575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        }
166575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        return track;
167575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    }
168575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber
169575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber    virtual sp<IAudioRecord> openRecord(
170717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                                audio_io_handle_t input,
171717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo                                uint32_t sampleRate,
172a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                                audio_format_t format,
173a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber                                audio_channel_mask_t channelMask,
17490fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                                size_t *pFrameCount,
17590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                                track_flags_t *flags,
17690fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                                pid_t tid,
17790fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                                int *sessionId,
17840d8899f60c5212af9d727ba0ffaaecf676ebd1dChih-Hung Hsieh                                size_t *notificationFrames,
17990fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                                sp<IMemory>& cblk,
1805778822d86b0337407514b9372562b86edfa91cdAndreas Huber                                sp<IMemory>& buffers,
1815778822d86b0337407514b9372562b86edfa91cdAndreas Huber                                status_t *status)
1825778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
1835778822d86b0337407514b9372562b86edfa91cdAndreas Huber        Parcel data, reply;
1845778822d86b0337407514b9372562b86edfa91cdAndreas Huber        sp<IAudioRecord> record;
18547a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
1864b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu        data.writeInt32((int32_t) input);
18747a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        data.writeInt32(sampleRate);
18847a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        data.writeInt32(format);
18947a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        data.writeInt32(channelMask);
1905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        size_t frameCount = pFrameCount != NULL ? *pFrameCount : 0;
1915778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeInt64(frameCount);
1925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT;
1935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeInt32(lFlags);
1945778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeInt32((int32_t) tid);
1955778822d86b0337407514b9372562b86edfa91cdAndreas Huber        int lSessionId = AUDIO_SESSION_ALLOCATE;
1965778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (sessionId != NULL) {
1975778822d86b0337407514b9372562b86edfa91cdAndreas Huber            lSessionId = *sessionId;
1985778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
1990e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar        data.writeInt32(lSessionId);
2005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeInt64(notificationFrames != NULL ? *notificationFrames : 0);
201c95c2ddcdfc974f42408a377fbe2de51b94a8c94Andreas Huber        cblk.clear();
2025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        buffers.clear();
2035778822d86b0337407514b9372562b86edfa91cdAndreas Huber        status_t lStatus = remote()->transact(OPEN_RECORD, data, &reply);
2045778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (lStatus != NO_ERROR) {
2055778822d86b0337407514b9372562b86edfa91cdAndreas Huber            ALOGE("openRecord error: %s", strerror(-lStatus));
2065778822d86b0337407514b9372562b86edfa91cdAndreas Huber        } else {
2075778822d86b0337407514b9372562b86edfa91cdAndreas Huber            frameCount = reply.readInt64();
2085778822d86b0337407514b9372562b86edfa91cdAndreas Huber            if (pFrameCount != NULL) {
2095778822d86b0337407514b9372562b86edfa91cdAndreas Huber                *pFrameCount = frameCount;
210575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            }
211575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            lFlags = reply.readInt32();
2121dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar            if (flags != NULL) {
2137cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden                *flags = lFlags;
2148f469e18c307cb9dc0d16ed9225972aa8be4516fChong Zhang            }
215575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            lSessionId = reply.readInt32();
216575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            if (sessionId != NULL) {
217575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                *sessionId = lSessionId;
218575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            }
219575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            size_t lNotificationFrames = (size_t) reply.readInt64();
220575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            if (notificationFrames != NULL) {
221575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                *notificationFrames = lNotificationFrames;
2227cd58537932ef6f481f68be0b9c597a89cebdfecAndy McFadden            }
223575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            lStatus = reply.readInt32();
224575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            record = interface_cast<IAudioRecord>(reply.readStrongBinder());
225575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            cblk = interface_cast<IMemory>(reply.readStrongBinder());
226e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar            if (cblk != 0 && cblk->pointer() == NULL) {
227575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                cblk.clear();
228575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            }
229575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            buffers = interface_cast<IMemory>(reply.readStrongBinder());
230575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber            if (buffers != 0 && buffers->pointer() == NULL) {
231575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber                buffers.clear();
232717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo            }
233a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber            if (lStatus == NO_ERROR) {
234c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                if (record == 0) {
23590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar                    ALOGE("openRecord should have returned an IAudioRecord");
2365778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    lStatus = UNKNOWN_ERROR;
2375778822d86b0337407514b9372562b86edfa91cdAndreas Huber                } else if (cblk == 0) {
2385778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGE("openRecord should have returned a cblk");
2393a01a71dcbb467d06cc5da4a72a82bb588648cfcLajos Molnar                    lStatus = NO_MEMORY;
2405778822d86b0337407514b9372562b86edfa91cdAndreas Huber                }
2415778822d86b0337407514b9372562b86edfa91cdAndreas Huber                // buffers is permitted to be 0
2425778822d86b0337407514b9372562b86edfa91cdAndreas Huber            } else {
2435778822d86b0337407514b9372562b86edfa91cdAndreas Huber                if (record != 0 || cblk != 0 || buffers != 0) {
2445778822d86b0337407514b9372562b86edfa91cdAndreas Huber                    ALOGE("openRecord returned an IAudioRecord, cblk, "
245ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber                          "or buffers but with status %d", lStatus);
246aa7f97bb9c70176245ffb7ed0ce52bee6c1a57d7Andreas Huber                }
247e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            }
248e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber            if (lStatus != NO_ERROR) {
249c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang                record.clear();
25052dfbee90cc3c4426428318e06a92774f5201198Praveen Chavan                cblk.clear();
2518b23759763dbf11b0c628a7e62dc5b3dea7dc188Lajos Molnar                buffers.clear();
2525778822d86b0337407514b9372562b86edfa91cdAndreas Huber            }
2535778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
2545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        if (status != NULL) {
255609b815a3131d22da38b2f452faa9f89daad4039Andy Hung            *status = lStatus;
2565778822d86b0337407514b9372562b86edfa91cdAndreas Huber        }
257a63141af8f036bda0b8f7800107ca8a0e0623135Lajos Molnar        return record;
25886b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu    }
259ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
260c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker    virtual uint32_t sampleRate(audio_io_handle_t output) const
2615778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
2627bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        Parcel data, reply;
2635778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
2645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeInt32((int32_t) output);
2655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        remote()->transact(SAMPLE_RATE, data, &reply);
26667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return reply.readInt32();
26768845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    }
26867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
26967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual audio_format_t format(audio_io_handle_t output) const
27067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    {
27167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        Parcel data, reply;
27267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
27367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        data.writeInt32((int32_t) output);
27467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        remote()->transact(FORMAT, data, &reply);
27567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return (audio_format_t) reply.readInt32();
27667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
27740d8899f60c5212af9d727ba0ffaaecf676ebd1dChih-Hung Hsieh
27867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual size_t frameCount(audio_io_handle_t output) const
27967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    {
28067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        Parcel data, reply;
28167e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
28237c8924c508a7c9b8bd3c8ce80fc005070531902Ronghua Wu        data.writeInt32((int32_t) output);
28367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        remote()->transact(FRAME_COUNT, data, &reply);
28467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        return reply.readInt64();
28567e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    }
28667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
28768845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu    virtual uint32_t latency(audio_io_handle_t output) const
28867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    {
28967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        Parcel data, reply;
2905778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
29147a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        data.writeInt32((int32_t) output);
2925778822d86b0337407514b9372562b86edfa91cdAndreas Huber        remote()->transact(LATENCY, data, &reply);
2935778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return reply.readInt32();
29492cd05b8f2e994aabcdda5d7454c96a707dc9579Lajos Molnar    }
295717fd3d4328abf524978ce9c125ab8ae8d6bffadMartin Storsjo
2963f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar    virtual status_t setMasterVolume(float value)
2975778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
298251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        Parcel data, reply;
299f06cc24ce7aeb5ff6f45b770a15286c95f8cc9ffLajos Molnar        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
3005778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeFloat(value);
30190fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar        remote()->transact(SET_MASTER_VOLUME, data, &reply);
3025778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return reply.readInt32();
303e0381245dff04aa823a59aa8b85869eddab0f39fLajos Molnar    }
304c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
30590fcf68fd29f3cb695bd53a830ad984cb7d430c0Lajos Molnar    virtual status_t setMasterMute(bool muted)
306c481b5012a5f6cf72e5e93b36f1ed4c9169916f2Jeff Tinker    {
3075778822d86b0337407514b9372562b86edfa91cdAndreas Huber        Parcel data, reply;
30867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
30967e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        data.writeInt32(muted);
31067e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        remote()->transact(SET_MASTER_MUTE, data, &reply);
3112606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        return reply.readInt32();
3122606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang    }
31367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
31467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual float masterVolume() const
315505aab41c0e8e79a49d4506344fcd9d220d5965bChong Zhang    {
3162606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        Parcel data, reply;
317671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
318671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        remote()->transact(MASTER_VOLUME, data, &reply);
319671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar        return reply.readFloat();
320671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar    }
321671160ffe81592efa376dc1ff0fc3f4ddcdebc35Lajos Molnar
32267e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    virtual bool masterMute() const
32367e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    {
32467e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu        Parcel data, reply;
3257bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
3267bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        remote()->transact(MASTER_MUTE, data, &reply);
3277bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        return reply.readInt32();
3287bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
3297bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
3307bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    virtual status_t setStreamVolume(audio_stream_type_t stream, float value,
3315778822d86b0337407514b9372562b86edfa91cdAndreas Huber            audio_io_handle_t output)
3325778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
3335778822d86b0337407514b9372562b86edfa91cdAndreas Huber        Parcel data, reply;
3345778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
3353f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        data.writeInt32((int32_t) stream);
3365778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeFloat(value);
3375778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeInt32((int32_t) output);
3383f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        remote()->transact(SET_STREAM_VOLUME, data, &reply);
3395778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return reply.readInt32();
340ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber    }
341ed3e3e046840d5bf1ca84a8c0cc097425e89d6d6Andreas Huber
3428ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    virtual status_t setStreamMute(audio_stream_type_t stream, bool muted)
3438ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    {
344575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        Parcel data, reply;
345575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
3466507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        data.writeInt32((int32_t) stream);
3473d66eb4128aebef31bb0fa44c4d53d6122294a26Chong Zhang        data.writeInt32(muted);
3486507d14c6d10f93d390de62b9eed267f9b544985Andy McFadden        remote()->transact(SET_STREAM_MUTE, data, &reply);
34968845c14ebf2c7282800b1abffde38d8e9a57aabRonghua Wu        return reply.readInt32();
3505778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
3515b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar
3525b05e49e6550cb2abf1a88272d6cd460b8957176Lajos Molnar    virtual float streamVolume(audio_stream_type_t stream, audio_io_handle_t output) const
3535778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
3545778822d86b0337407514b9372562b86edfa91cdAndreas Huber        Parcel data, reply;
3555778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
35647a2e875bdd2bd25cb8500208940ff1488b01e08Ronghua Wu        data.writeInt32((int32_t) stream);
357c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        data.writeInt32((int32_t) output);
358dc9f58dc23a86d0635fd8601d1cbc8d47bab0303Andy Hung        remote()->transact(STREAM_VOLUME, data, &reply);
3595778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return reply.readFloat();
3605778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
36186b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu
36286b997dcf1101cdd259460fb4f82204200a9a993Ronghua Wu    virtual bool streamMute(audio_stream_type_t stream) const
3635778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
3645778822d86b0337407514b9372562b86edfa91cdAndreas Huber        Parcel data, reply;
3655778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
3665778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeInt32((int32_t) stream);
3675778822d86b0337407514b9372562b86edfa91cdAndreas Huber        remote()->transact(STREAM_MUTE, data, &reply);
3687bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar        return reply.readInt32();
3697bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    }
3707bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar
3717bad72237b49ac47e77ffe2a89fd26f3d171324cLajos Molnar    virtual status_t setMode(audio_mode_t mode)
3723f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar    {
3733f27436a9346f043f52265da1e6a74cde2bffd4dLajos Molnar        Parcel data, reply;
3745778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
3755778822d86b0337407514b9372562b86edfa91cdAndreas Huber        data.writeInt32(mode);
3768ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        remote()->transact(SET_MODE, data, &reply);
3778ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber        return reply.readInt32();
3788ee516a515c70a492c395b67ce12e19e7d159804Andreas Huber    }
3791dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar
3801dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    virtual status_t setMicMute(bool state)
3811dcdfead2971c1fa7c02f24ba86f706890c9f99eLajos Molnar    {
3827541ff5d83a3e77cb533841a0326a241550b95d9Andreas Huber        Parcel data, reply;
383575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
384575a5361fc970476cd7979638ee3ac00cc6e5024Andreas Huber        data.writeInt32(state);
385c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        remote()->transact(SET_MIC_MUTE, data, &reply);
386c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang        return reply.readInt32();
387749dafad09d85f2aaf6902a7ff16b4087e3bc4c7Chong Zhang    }
388c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang
389c5619c7a6dcc1137fde7520351ad5284e3e958abChong Zhang    virtual bool getMicMute() const
390a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber    {
391a2eb22c1de262aa3fa7c356537ac2fe165afdf3dAndreas Huber        Parcel data, reply;
392e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
3932606b10d51c2dceb851a2ea63e803aba4134bf00Chong Zhang        remote()->transact(GET_MIC_MUTE, data, &reply);
3940e8cfc36044ba97545e7c9e129b0b3e98eec5089Lajos Molnar        return reply.readInt32();
395e96ee699aca0f711d41e6c0833e5de2341c4a36dAndreas Huber    }
39667e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu
397ea15fd29af81490311af9e12949b43524c39400eRonghua Wu    virtual status_t setParameters(audio_io_handle_t ioHandle, const String8& keyValuePairs)
39867e7f543c7f1c4fe4ee1989ceb0aebe44a63b49eRonghua Wu    {
3994b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu        Parcel data, reply;
4004b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
4014b710f086070fabe022b3a1f474bfcbec842b8fcRonghua Wu        data.writeInt32((int32_t) ioHandle);
402251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        data.writeString8(keyValuePairs);
403251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        remote()->transact(SET_PARAMETERS, data, &reply);
404251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        return reply.readInt32();
405251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    }
406251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung
407251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    virtual String8 getParameters(audio_io_handle_t ioHandle, const String8& keys) const
408251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung    {
409251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        Parcel data, reply;
410251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
411251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        data.writeInt32((int32_t) ioHandle);
412251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        data.writeString8(keys);
413251d4be8aa5ab80bc915a82a2420233bdc62018eAndy Hung        remote()->transact(GET_PARAMETERS, data, &reply);
4145778822d86b0337407514b9372562b86edfa91cdAndreas Huber        return reply.readString8();
4155778822d86b0337407514b9372562b86edfa91cdAndreas Huber    }
4165778822d86b0337407514b9372562b86edfa91cdAndreas Huber
4175778822d86b0337407514b9372562b86edfa91cdAndreas Huber    virtual void registerClient(const sp<IAudioFlingerClient>& client)
4185778822d86b0337407514b9372562b86edfa91cdAndreas Huber    {
4195778822d86b0337407514b9372562b86edfa91cdAndreas Huber        Parcel data, reply;
420        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
421        data.writeStrongBinder(client->asBinder());
422        remote()->transact(REGISTER_CLIENT, data, &reply);
423    }
424
425    virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
426            audio_channel_mask_t channelMask) const
427    {
428        Parcel data, reply;
429        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
430        data.writeInt32(sampleRate);
431        data.writeInt32(format);
432        data.writeInt32(channelMask);
433        remote()->transact(GET_INPUTBUFFERSIZE, data, &reply);
434        return reply.readInt64();
435    }
436
437    virtual status_t openOutput(audio_module_handle_t module,
438                                audio_io_handle_t *output,
439                                audio_config_t *config,
440                                audio_devices_t *devices,
441                                const String8& address,
442                                uint32_t *latencyMs,
443                                audio_output_flags_t flags)
444    {
445        if (output == NULL || config == NULL || devices == NULL || latencyMs == NULL) {
446            return BAD_VALUE;
447        }
448        Parcel data, reply;
449        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
450        data.writeInt32(module);
451        data.write(config, sizeof(audio_config_t));
452        data.writeInt32(*devices);
453        data.writeString8(address);
454        data.writeInt32((int32_t) flags);
455        status_t status = remote()->transact(OPEN_OUTPUT, data, &reply);
456        if (status != NO_ERROR) {
457            *output = AUDIO_IO_HANDLE_NONE;
458            return status;
459        }
460        status = (status_t)reply.readInt32();
461        if (status != NO_ERROR) {
462            *output = AUDIO_IO_HANDLE_NONE;
463            return status;
464        }
465        *output = (audio_io_handle_t)reply.readInt32();
466        ALOGV("openOutput() returned output, %d", *output);
467        reply.read(config, sizeof(audio_config_t));
468        *devices = (audio_devices_t)reply.readInt32();
469        *latencyMs = reply.readInt32();
470        return NO_ERROR;
471    }
472
473    virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
474            audio_io_handle_t output2)
475    {
476        Parcel data, reply;
477        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
478        data.writeInt32((int32_t) output1);
479        data.writeInt32((int32_t) output2);
480        remote()->transact(OPEN_DUPLICATE_OUTPUT, data, &reply);
481        return (audio_io_handle_t) reply.readInt32();
482    }
483
484    virtual status_t closeOutput(audio_io_handle_t output)
485    {
486        Parcel data, reply;
487        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
488        data.writeInt32((int32_t) output);
489        remote()->transact(CLOSE_OUTPUT, data, &reply);
490        return reply.readInt32();
491    }
492
493    virtual status_t suspendOutput(audio_io_handle_t output)
494    {
495        Parcel data, reply;
496        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
497        data.writeInt32((int32_t) output);
498        remote()->transact(SUSPEND_OUTPUT, data, &reply);
499        return reply.readInt32();
500    }
501
502    virtual status_t restoreOutput(audio_io_handle_t output)
503    {
504        Parcel data, reply;
505        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
506        data.writeInt32((int32_t) output);
507        remote()->transact(RESTORE_OUTPUT, data, &reply);
508        return reply.readInt32();
509    }
510
511    virtual status_t openInput(audio_module_handle_t module,
512                               audio_io_handle_t *input,
513                               audio_config_t *config,
514                               audio_devices_t *device,
515                               const String8& address,
516                               audio_source_t source,
517                               audio_input_flags_t flags)
518    {
519        if (input == NULL || config == NULL || device == NULL) {
520            return BAD_VALUE;
521        }
522        Parcel data, reply;
523        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
524        data.writeInt32(module);
525        data.writeInt32(*input);
526        data.write(config, sizeof(audio_config_t));
527        data.writeInt32(*device);
528        data.writeString8(address);
529        data.writeInt32(source);
530        data.writeInt32(flags);
531        status_t status = remote()->transact(OPEN_INPUT, data, &reply);
532        if (status != NO_ERROR) {
533            *input = AUDIO_IO_HANDLE_NONE;
534            return status;
535        }
536        status = (status_t)reply.readInt32();
537        if (status != NO_ERROR) {
538            *input = AUDIO_IO_HANDLE_NONE;
539            return status;
540        }
541        *input = (audio_io_handle_t)reply.readInt32();
542        reply.read(config, sizeof(audio_config_t));
543        *device = (audio_devices_t)reply.readInt32();
544        return NO_ERROR;
545    }
546
547    virtual status_t closeInput(int input)
548    {
549        Parcel data, reply;
550        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
551        data.writeInt32(input);
552        remote()->transact(CLOSE_INPUT, data, &reply);
553        return reply.readInt32();
554    }
555
556    virtual status_t invalidateStream(audio_stream_type_t stream)
557    {
558        Parcel data, reply;
559        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
560        data.writeInt32((int32_t) stream);
561        remote()->transact(INVALIDATE_STREAM, data, &reply);
562        return reply.readInt32();
563    }
564
565    virtual status_t setVoiceVolume(float volume)
566    {
567        Parcel data, reply;
568        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
569        data.writeFloat(volume);
570        remote()->transact(SET_VOICE_VOLUME, data, &reply);
571        return reply.readInt32();
572    }
573
574    virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
575            audio_io_handle_t output) const
576    {
577        Parcel data, reply;
578        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
579        data.writeInt32((int32_t) output);
580        remote()->transact(GET_RENDER_POSITION, data, &reply);
581        status_t status = reply.readInt32();
582        if (status == NO_ERROR) {
583            uint32_t tmp = reply.readInt32();
584            if (halFrames != NULL) {
585                *halFrames = tmp;
586            }
587            tmp = reply.readInt32();
588            if (dspFrames != NULL) {
589                *dspFrames = tmp;
590            }
591        }
592        return status;
593    }
594
595    virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const
596    {
597        Parcel data, reply;
598        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
599        data.writeInt32((int32_t) ioHandle);
600        status_t status = remote()->transact(GET_INPUT_FRAMES_LOST, data, &reply);
601        if (status != NO_ERROR) {
602            return 0;
603        }
604        return (uint32_t) reply.readInt32();
605    }
606
607    virtual audio_unique_id_t newAudioUniqueId()
608    {
609        Parcel data, reply;
610        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
611        status_t status = remote()->transact(NEW_AUDIO_SESSION_ID, data, &reply);
612        audio_unique_id_t id = AUDIO_SESSION_ALLOCATE;
613        if (status == NO_ERROR) {
614            id = reply.readInt32();
615        }
616        return id;
617    }
618
619    virtual void acquireAudioSessionId(int audioSession, int pid)
620    {
621        Parcel data, reply;
622        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
623        data.writeInt32(audioSession);
624        data.writeInt32(pid);
625        remote()->transact(ACQUIRE_AUDIO_SESSION_ID, data, &reply);
626    }
627
628    virtual void releaseAudioSessionId(int audioSession, int pid)
629    {
630        Parcel data, reply;
631        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
632        data.writeInt32(audioSession);
633        data.writeInt32(pid);
634        remote()->transact(RELEASE_AUDIO_SESSION_ID, data, &reply);
635    }
636
637    virtual status_t queryNumberEffects(uint32_t *numEffects) const
638    {
639        Parcel data, reply;
640        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
641        status_t status = remote()->transact(QUERY_NUM_EFFECTS, 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        if (numEffects != NULL) {
650            *numEffects = (uint32_t)reply.readInt32();
651        }
652        return NO_ERROR;
653    }
654
655    virtual status_t queryEffect(uint32_t index, effect_descriptor_t *pDescriptor) const
656    {
657        if (pDescriptor == NULL) {
658            return BAD_VALUE;
659        }
660        Parcel data, reply;
661        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
662        data.writeInt32(index);
663        status_t status = remote()->transact(QUERY_EFFECT, data, &reply);
664        if (status != NO_ERROR) {
665            return status;
666        }
667        status = reply.readInt32();
668        if (status != NO_ERROR) {
669            return status;
670        }
671        reply.read(pDescriptor, sizeof(effect_descriptor_t));
672        return NO_ERROR;
673    }
674
675    virtual status_t getEffectDescriptor(const effect_uuid_t *pUuid,
676            effect_descriptor_t *pDescriptor) const
677    {
678        if (pUuid == NULL || pDescriptor == NULL) {
679            return BAD_VALUE;
680        }
681        Parcel data, reply;
682        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
683        data.write(pUuid, sizeof(effect_uuid_t));
684        status_t status = remote()->transact(GET_EFFECT_DESCRIPTOR, data, &reply);
685        if (status != NO_ERROR) {
686            return status;
687        }
688        status = reply.readInt32();
689        if (status != NO_ERROR) {
690            return status;
691        }
692        reply.read(pDescriptor, sizeof(effect_descriptor_t));
693        return NO_ERROR;
694    }
695
696    virtual sp<IEffect> createEffect(
697                                    effect_descriptor_t *pDesc,
698                                    const sp<IEffectClient>& client,
699                                    int32_t priority,
700                                    audio_io_handle_t output,
701                                    int sessionId,
702                                    status_t *status,
703                                    int *id,
704                                    int *enabled)
705    {
706        Parcel data, reply;
707        sp<IEffect> effect;
708
709        if (pDesc == NULL) {
710            return effect;
711            if (status != NULL) {
712                *status = BAD_VALUE;
713            }
714        }
715
716        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
717        data.write(pDesc, sizeof(effect_descriptor_t));
718        data.writeStrongBinder(client->asBinder());
719        data.writeInt32(priority);
720        data.writeInt32((int32_t) output);
721        data.writeInt32(sessionId);
722
723        status_t lStatus = remote()->transact(CREATE_EFFECT, data, &reply);
724        if (lStatus != NO_ERROR) {
725            ALOGE("createEffect error: %s", strerror(-lStatus));
726        } else {
727            lStatus = reply.readInt32();
728            int tmp = reply.readInt32();
729            if (id != NULL) {
730                *id = tmp;
731            }
732            tmp = reply.readInt32();
733            if (enabled != NULL) {
734                *enabled = tmp;
735            }
736            effect = interface_cast<IEffect>(reply.readStrongBinder());
737            reply.read(pDesc, sizeof(effect_descriptor_t));
738        }
739        if (status != NULL) {
740            *status = lStatus;
741        }
742
743        return effect;
744    }
745
746    virtual status_t moveEffects(int session, audio_io_handle_t srcOutput,
747            audio_io_handle_t dstOutput)
748    {
749        Parcel data, reply;
750        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
751        data.writeInt32(session);
752        data.writeInt32((int32_t) srcOutput);
753        data.writeInt32((int32_t) dstOutput);
754        remote()->transact(MOVE_EFFECTS, data, &reply);
755        return reply.readInt32();
756    }
757
758    virtual audio_module_handle_t loadHwModule(const char *name)
759    {
760        Parcel data, reply;
761        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
762        data.writeCString(name);
763        remote()->transact(LOAD_HW_MODULE, data, &reply);
764        return (audio_module_handle_t) reply.readInt32();
765    }
766
767    virtual uint32_t getPrimaryOutputSamplingRate()
768    {
769        Parcel data, reply;
770        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
771        remote()->transact(GET_PRIMARY_OUTPUT_SAMPLING_RATE, data, &reply);
772        return reply.readInt32();
773    }
774
775    virtual size_t getPrimaryOutputFrameCount()
776    {
777        Parcel data, reply;
778        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
779        remote()->transact(GET_PRIMARY_OUTPUT_FRAME_COUNT, data, &reply);
780        return reply.readInt64();
781    }
782
783    virtual status_t setLowRamDevice(bool isLowRamDevice)
784    {
785        Parcel data, reply;
786        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
787        data.writeInt32((int) isLowRamDevice);
788        remote()->transact(SET_LOW_RAM_DEVICE, data, &reply);
789        return reply.readInt32();
790    }
791    virtual status_t listAudioPorts(unsigned int *num_ports,
792                                    struct audio_port *ports)
793    {
794        if (num_ports == NULL || *num_ports == 0 || ports == NULL) {
795            return BAD_VALUE;
796        }
797        Parcel data, reply;
798        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
799        data.writeInt32(*num_ports);
800        status_t status = remote()->transact(LIST_AUDIO_PORTS, data, &reply);
801        if (status != NO_ERROR ||
802                (status = (status_t)reply.readInt32()) != NO_ERROR) {
803            return status;
804        }
805        *num_ports = (unsigned int)reply.readInt32();
806        reply.read(ports, *num_ports * sizeof(struct audio_port));
807        return status;
808    }
809    virtual status_t getAudioPort(struct audio_port *port)
810    {
811        if (port == NULL) {
812            return BAD_VALUE;
813        }
814        Parcel data, reply;
815        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
816        data.write(port, sizeof(struct audio_port));
817        status_t status = remote()->transact(GET_AUDIO_PORT, data, &reply);
818        if (status != NO_ERROR ||
819                (status = (status_t)reply.readInt32()) != NO_ERROR) {
820            return status;
821        }
822        reply.read(port, sizeof(struct audio_port));
823        return status;
824    }
825    virtual status_t createAudioPatch(const struct audio_patch *patch,
826                                       audio_patch_handle_t *handle)
827    {
828        if (patch == NULL || handle == NULL) {
829            return BAD_VALUE;
830        }
831        Parcel data, reply;
832        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
833        data.write(patch, sizeof(struct audio_patch));
834        data.write(handle, sizeof(audio_patch_handle_t));
835        status_t status = remote()->transact(CREATE_AUDIO_PATCH, data, &reply);
836        if (status != NO_ERROR ||
837                (status = (status_t)reply.readInt32()) != NO_ERROR) {
838            return status;
839        }
840        reply.read(handle, sizeof(audio_patch_handle_t));
841        return status;
842    }
843    virtual status_t releaseAudioPatch(audio_patch_handle_t handle)
844    {
845        Parcel data, reply;
846        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
847        data.write(&handle, sizeof(audio_patch_handle_t));
848        status_t status = remote()->transact(RELEASE_AUDIO_PATCH, data, &reply);
849        if (status != NO_ERROR) {
850            status = (status_t)reply.readInt32();
851        }
852        return status;
853    }
854    virtual status_t listAudioPatches(unsigned int *num_patches,
855                                      struct audio_patch *patches)
856    {
857        if (num_patches == NULL || *num_patches == 0 || patches == NULL) {
858            return BAD_VALUE;
859        }
860        Parcel data, reply;
861        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
862        data.writeInt32(*num_patches);
863        status_t status = remote()->transact(LIST_AUDIO_PATCHES, data, &reply);
864        if (status != NO_ERROR ||
865                (status = (status_t)reply.readInt32()) != NO_ERROR) {
866            return status;
867        }
868        *num_patches = (unsigned int)reply.readInt32();
869        reply.read(patches, *num_patches * sizeof(struct audio_patch));
870        return status;
871    }
872    virtual status_t setAudioPortConfig(const struct audio_port_config *config)
873    {
874        if (config == NULL) {
875            return BAD_VALUE;
876        }
877        Parcel data, reply;
878        data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
879        data.write(config, sizeof(struct audio_port_config));
880        status_t status = remote()->transact(SET_AUDIO_PORT_CONFIG, data, &reply);
881        if (status != NO_ERROR) {
882            status = (status_t)reply.readInt32();
883        }
884        return status;
885    }
886};
887
888IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
889
890// ----------------------------------------------------------------------
891
892status_t BnAudioFlinger::onTransact(
893    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
894{
895    switch (code) {
896        case CREATE_TRACK: {
897            CHECK_INTERFACE(IAudioFlinger, data, reply);
898            int streamType = data.readInt32();
899            uint32_t sampleRate = data.readInt32();
900            audio_format_t format = (audio_format_t) data.readInt32();
901            audio_channel_mask_t channelMask = data.readInt32();
902            size_t frameCount = data.readInt64();
903            track_flags_t flags = (track_flags_t) data.readInt32();
904            bool haveSharedBuffer = data.readInt32() != 0;
905            sp<IMemory> buffer;
906            if (haveSharedBuffer) {
907                buffer = interface_cast<IMemory>(data.readStrongBinder());
908            }
909            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
910            pid_t tid = (pid_t) data.readInt32();
911            int sessionId = data.readInt32();
912            int clientUid = data.readInt32();
913            status_t status;
914            sp<IAudioTrack> track;
915            if ((haveSharedBuffer && (buffer == 0)) ||
916                    ((buffer != 0) && (buffer->pointer() == NULL))) {
917                ALOGW("CREATE_TRACK: cannot retrieve shared memory");
918                status = DEAD_OBJECT;
919            } else {
920                track = createTrack(
921                        (audio_stream_type_t) streamType, sampleRate, format,
922                        channelMask, &frameCount, &flags, buffer, output, tid,
923                        &sessionId, clientUid, &status);
924                LOG_ALWAYS_FATAL_IF((track != 0) != (status == NO_ERROR));
925            }
926            reply->writeInt64(frameCount);
927            reply->writeInt32(flags);
928            reply->writeInt32(sessionId);
929            reply->writeInt32(status);
930            reply->writeStrongBinder(track->asBinder());
931            return NO_ERROR;
932        } break;
933        case OPEN_RECORD: {
934            CHECK_INTERFACE(IAudioFlinger, data, reply);
935            audio_io_handle_t input = (audio_io_handle_t) data.readInt32();
936            uint32_t sampleRate = data.readInt32();
937            audio_format_t format = (audio_format_t) data.readInt32();
938            audio_channel_mask_t channelMask = data.readInt32();
939            size_t frameCount = data.readInt64();
940            track_flags_t flags = (track_flags_t) data.readInt32();
941            pid_t tid = (pid_t) data.readInt32();
942            int sessionId = data.readInt32();
943            size_t notificationFrames = data.readInt64();
944            sp<IMemory> cblk;
945            sp<IMemory> buffers;
946            status_t status;
947            sp<IAudioRecord> record = openRecord(input,
948                    sampleRate, format, channelMask, &frameCount, &flags, tid, &sessionId,
949                    &notificationFrames,
950                    cblk, buffers, &status);
951            LOG_ALWAYS_FATAL_IF((record != 0) != (status == NO_ERROR));
952            reply->writeInt64(frameCount);
953            reply->writeInt32(flags);
954            reply->writeInt32(sessionId);
955            reply->writeInt64(notificationFrames);
956            reply->writeInt32(status);
957            reply->writeStrongBinder(record->asBinder());
958            reply->writeStrongBinder(cblk->asBinder());
959            reply->writeStrongBinder(buffers->asBinder());
960            return NO_ERROR;
961        } break;
962        case SAMPLE_RATE: {
963            CHECK_INTERFACE(IAudioFlinger, data, reply);
964            reply->writeInt32( sampleRate((audio_io_handle_t) data.readInt32()) );
965            return NO_ERROR;
966        } break;
967        case FORMAT: {
968            CHECK_INTERFACE(IAudioFlinger, data, reply);
969            reply->writeInt32( format((audio_io_handle_t) data.readInt32()) );
970            return NO_ERROR;
971        } break;
972        case FRAME_COUNT: {
973            CHECK_INTERFACE(IAudioFlinger, data, reply);
974            reply->writeInt64( frameCount((audio_io_handle_t) data.readInt32()) );
975            return NO_ERROR;
976        } break;
977        case LATENCY: {
978            CHECK_INTERFACE(IAudioFlinger, data, reply);
979            reply->writeInt32( latency((audio_io_handle_t) data.readInt32()) );
980            return NO_ERROR;
981        } break;
982        case SET_MASTER_VOLUME: {
983            CHECK_INTERFACE(IAudioFlinger, data, reply);
984            reply->writeInt32( setMasterVolume(data.readFloat()) );
985            return NO_ERROR;
986        } break;
987        case SET_MASTER_MUTE: {
988            CHECK_INTERFACE(IAudioFlinger, data, reply);
989            reply->writeInt32( setMasterMute(data.readInt32()) );
990            return NO_ERROR;
991        } break;
992        case MASTER_VOLUME: {
993            CHECK_INTERFACE(IAudioFlinger, data, reply);
994            reply->writeFloat( masterVolume() );
995            return NO_ERROR;
996        } break;
997        case MASTER_MUTE: {
998            CHECK_INTERFACE(IAudioFlinger, data, reply);
999            reply->writeInt32( masterMute() );
1000            return NO_ERROR;
1001        } break;
1002        case SET_STREAM_VOLUME: {
1003            CHECK_INTERFACE(IAudioFlinger, data, reply);
1004            int stream = data.readInt32();
1005            float volume = data.readFloat();
1006            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
1007            reply->writeInt32( setStreamVolume((audio_stream_type_t) stream, volume, output) );
1008            return NO_ERROR;
1009        } break;
1010        case SET_STREAM_MUTE: {
1011            CHECK_INTERFACE(IAudioFlinger, data, reply);
1012            int stream = data.readInt32();
1013            reply->writeInt32( setStreamMute((audio_stream_type_t) stream, data.readInt32()) );
1014            return NO_ERROR;
1015        } break;
1016        case STREAM_VOLUME: {
1017            CHECK_INTERFACE(IAudioFlinger, data, reply);
1018            int stream = data.readInt32();
1019            int output = data.readInt32();
1020            reply->writeFloat( streamVolume((audio_stream_type_t) stream, output) );
1021            return NO_ERROR;
1022        } break;
1023        case STREAM_MUTE: {
1024            CHECK_INTERFACE(IAudioFlinger, data, reply);
1025            int stream = data.readInt32();
1026            reply->writeInt32( streamMute((audio_stream_type_t) stream) );
1027            return NO_ERROR;
1028        } break;
1029        case SET_MODE: {
1030            CHECK_INTERFACE(IAudioFlinger, data, reply);
1031            audio_mode_t mode = (audio_mode_t) data.readInt32();
1032            reply->writeInt32( setMode(mode) );
1033            return NO_ERROR;
1034        } break;
1035        case SET_MIC_MUTE: {
1036            CHECK_INTERFACE(IAudioFlinger, data, reply);
1037            int state = data.readInt32();
1038            reply->writeInt32( setMicMute(state) );
1039            return NO_ERROR;
1040        } break;
1041        case GET_MIC_MUTE: {
1042            CHECK_INTERFACE(IAudioFlinger, data, reply);
1043            reply->writeInt32( getMicMute() );
1044            return NO_ERROR;
1045        } break;
1046        case SET_PARAMETERS: {
1047            CHECK_INTERFACE(IAudioFlinger, data, reply);
1048            audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32();
1049            String8 keyValuePairs(data.readString8());
1050            reply->writeInt32(setParameters(ioHandle, keyValuePairs));
1051            return NO_ERROR;
1052        } break;
1053        case GET_PARAMETERS: {
1054            CHECK_INTERFACE(IAudioFlinger, data, reply);
1055            audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32();
1056            String8 keys(data.readString8());
1057            reply->writeString8(getParameters(ioHandle, keys));
1058            return NO_ERROR;
1059        } break;
1060
1061        case REGISTER_CLIENT: {
1062            CHECK_INTERFACE(IAudioFlinger, data, reply);
1063            sp<IAudioFlingerClient> client = interface_cast<IAudioFlingerClient>(
1064                    data.readStrongBinder());
1065            registerClient(client);
1066            return NO_ERROR;
1067        } break;
1068        case GET_INPUTBUFFERSIZE: {
1069            CHECK_INTERFACE(IAudioFlinger, data, reply);
1070            uint32_t sampleRate = data.readInt32();
1071            audio_format_t format = (audio_format_t) data.readInt32();
1072            audio_channel_mask_t channelMask = data.readInt32();
1073            reply->writeInt64( getInputBufferSize(sampleRate, format, channelMask) );
1074            return NO_ERROR;
1075        } break;
1076        case OPEN_OUTPUT: {
1077            CHECK_INTERFACE(IAudioFlinger, data, reply);
1078            audio_module_handle_t module = (audio_module_handle_t)data.readInt32();
1079            audio_config_t config;
1080            data.read(&config, sizeof(audio_config_t));
1081            audio_devices_t devices = (audio_devices_t)data.readInt32();
1082            String8 address(data.readString8());
1083            audio_output_flags_t flags = (audio_output_flags_t) data.readInt32();
1084            uint32_t latencyMs;
1085            audio_io_handle_t output;
1086            status_t status = openOutput(module, &output, &config,
1087                                         &devices, address, &latencyMs, flags);
1088            ALOGV("OPEN_OUTPUT output, %d", output);
1089            reply->writeInt32((int32_t)status);
1090            if (status == NO_ERROR) {
1091                reply->writeInt32((int32_t)output);
1092                reply->write(&config, sizeof(audio_config_t));
1093                reply->writeInt32(devices);
1094                reply->writeInt32(latencyMs);
1095            }
1096            return NO_ERROR;
1097        } break;
1098        case OPEN_DUPLICATE_OUTPUT: {
1099            CHECK_INTERFACE(IAudioFlinger, data, reply);
1100            audio_io_handle_t output1 = (audio_io_handle_t) data.readInt32();
1101            audio_io_handle_t output2 = (audio_io_handle_t) data.readInt32();
1102            reply->writeInt32((int32_t) openDuplicateOutput(output1, output2));
1103            return NO_ERROR;
1104        } break;
1105        case CLOSE_OUTPUT: {
1106            CHECK_INTERFACE(IAudioFlinger, data, reply);
1107            reply->writeInt32(closeOutput((audio_io_handle_t) data.readInt32()));
1108            return NO_ERROR;
1109        } break;
1110        case SUSPEND_OUTPUT: {
1111            CHECK_INTERFACE(IAudioFlinger, data, reply);
1112            reply->writeInt32(suspendOutput((audio_io_handle_t) data.readInt32()));
1113            return NO_ERROR;
1114        } break;
1115        case RESTORE_OUTPUT: {
1116            CHECK_INTERFACE(IAudioFlinger, data, reply);
1117            reply->writeInt32(restoreOutput((audio_io_handle_t) data.readInt32()));
1118            return NO_ERROR;
1119        } break;
1120        case OPEN_INPUT: {
1121            CHECK_INTERFACE(IAudioFlinger, data, reply);
1122            audio_module_handle_t module = (audio_module_handle_t)data.readInt32();
1123            audio_io_handle_t input = (audio_io_handle_t)data.readInt32();
1124            audio_config_t config;
1125            data.read(&config, sizeof(audio_config_t));
1126            audio_devices_t device = (audio_devices_t)data.readInt32();
1127            String8 address(data.readString8());
1128            audio_source_t source = (audio_source_t)data.readInt32();
1129            audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
1130
1131            status_t status = openInput(module, &input, &config,
1132                                        &device, address, source, flags);
1133            reply->writeInt32((int32_t) status);
1134            if (status == NO_ERROR) {
1135                reply->writeInt32((int32_t) input);
1136                reply->write(&config, sizeof(audio_config_t));
1137                reply->writeInt32(device);
1138            }
1139            return NO_ERROR;
1140        } break;
1141        case CLOSE_INPUT: {
1142            CHECK_INTERFACE(IAudioFlinger, data, reply);
1143            reply->writeInt32(closeInput((audio_io_handle_t) data.readInt32()));
1144            return NO_ERROR;
1145        } break;
1146        case INVALIDATE_STREAM: {
1147            CHECK_INTERFACE(IAudioFlinger, data, reply);
1148            audio_stream_type_t stream = (audio_stream_type_t) data.readInt32();
1149            reply->writeInt32(invalidateStream(stream));
1150            return NO_ERROR;
1151        } break;
1152        case SET_VOICE_VOLUME: {
1153            CHECK_INTERFACE(IAudioFlinger, data, reply);
1154            float volume = data.readFloat();
1155            reply->writeInt32( setVoiceVolume(volume) );
1156            return NO_ERROR;
1157        } break;
1158        case GET_RENDER_POSITION: {
1159            CHECK_INTERFACE(IAudioFlinger, data, reply);
1160            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
1161            uint32_t halFrames;
1162            uint32_t dspFrames;
1163            status_t status = getRenderPosition(&halFrames, &dspFrames, output);
1164            reply->writeInt32(status);
1165            if (status == NO_ERROR) {
1166                reply->writeInt32(halFrames);
1167                reply->writeInt32(dspFrames);
1168            }
1169            return NO_ERROR;
1170        }
1171        case GET_INPUT_FRAMES_LOST: {
1172            CHECK_INTERFACE(IAudioFlinger, data, reply);
1173            audio_io_handle_t ioHandle = (audio_io_handle_t) data.readInt32();
1174            reply->writeInt32((int32_t) getInputFramesLost(ioHandle));
1175            return NO_ERROR;
1176        } break;
1177        case NEW_AUDIO_SESSION_ID: {
1178            CHECK_INTERFACE(IAudioFlinger, data, reply);
1179            reply->writeInt32(newAudioUniqueId());
1180            return NO_ERROR;
1181        } break;
1182        case ACQUIRE_AUDIO_SESSION_ID: {
1183            CHECK_INTERFACE(IAudioFlinger, data, reply);
1184            int audioSession = data.readInt32();
1185            int pid = data.readInt32();
1186            acquireAudioSessionId(audioSession, pid);
1187            return NO_ERROR;
1188        } break;
1189        case RELEASE_AUDIO_SESSION_ID: {
1190            CHECK_INTERFACE(IAudioFlinger, data, reply);
1191            int audioSession = data.readInt32();
1192            int pid = data.readInt32();
1193            releaseAudioSessionId(audioSession, pid);
1194            return NO_ERROR;
1195        } break;
1196        case QUERY_NUM_EFFECTS: {
1197            CHECK_INTERFACE(IAudioFlinger, data, reply);
1198            uint32_t numEffects;
1199            status_t status = queryNumberEffects(&numEffects);
1200            reply->writeInt32(status);
1201            if (status == NO_ERROR) {
1202                reply->writeInt32((int32_t)numEffects);
1203            }
1204            return NO_ERROR;
1205        }
1206        case QUERY_EFFECT: {
1207            CHECK_INTERFACE(IAudioFlinger, data, reply);
1208            effect_descriptor_t desc;
1209            status_t status = queryEffect(data.readInt32(), &desc);
1210            reply->writeInt32(status);
1211            if (status == NO_ERROR) {
1212                reply->write(&desc, sizeof(effect_descriptor_t));
1213            }
1214            return NO_ERROR;
1215        }
1216        case GET_EFFECT_DESCRIPTOR: {
1217            CHECK_INTERFACE(IAudioFlinger, data, reply);
1218            effect_uuid_t uuid;
1219            data.read(&uuid, sizeof(effect_uuid_t));
1220            effect_descriptor_t desc;
1221            status_t status = getEffectDescriptor(&uuid, &desc);
1222            reply->writeInt32(status);
1223            if (status == NO_ERROR) {
1224                reply->write(&desc, sizeof(effect_descriptor_t));
1225            }
1226            return NO_ERROR;
1227        }
1228        case CREATE_EFFECT: {
1229            CHECK_INTERFACE(IAudioFlinger, data, reply);
1230            effect_descriptor_t desc;
1231            data.read(&desc, sizeof(effect_descriptor_t));
1232            sp<IEffectClient> client = interface_cast<IEffectClient>(data.readStrongBinder());
1233            int32_t priority = data.readInt32();
1234            audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
1235            int sessionId = data.readInt32();
1236            status_t status;
1237            int id;
1238            int enabled;
1239
1240            sp<IEffect> effect = createEffect(&desc, client, priority, output, sessionId,
1241                    &status, &id, &enabled);
1242            reply->writeInt32(status);
1243            reply->writeInt32(id);
1244            reply->writeInt32(enabled);
1245            reply->writeStrongBinder(effect->asBinder());
1246            reply->write(&desc, sizeof(effect_descriptor_t));
1247            return NO_ERROR;
1248        } break;
1249        case MOVE_EFFECTS: {
1250            CHECK_INTERFACE(IAudioFlinger, data, reply);
1251            int session = data.readInt32();
1252            audio_io_handle_t srcOutput = (audio_io_handle_t) data.readInt32();
1253            audio_io_handle_t dstOutput = (audio_io_handle_t) data.readInt32();
1254            reply->writeInt32(moveEffects(session, srcOutput, dstOutput));
1255            return NO_ERROR;
1256        } break;
1257        case LOAD_HW_MODULE: {
1258            CHECK_INTERFACE(IAudioFlinger, data, reply);
1259            reply->writeInt32(loadHwModule(data.readCString()));
1260            return NO_ERROR;
1261        } break;
1262        case GET_PRIMARY_OUTPUT_SAMPLING_RATE: {
1263            CHECK_INTERFACE(IAudioFlinger, data, reply);
1264            reply->writeInt32(getPrimaryOutputSamplingRate());
1265            return NO_ERROR;
1266        } break;
1267        case GET_PRIMARY_OUTPUT_FRAME_COUNT: {
1268            CHECK_INTERFACE(IAudioFlinger, data, reply);
1269            reply->writeInt64(getPrimaryOutputFrameCount());
1270            return NO_ERROR;
1271        } break;
1272        case SET_LOW_RAM_DEVICE: {
1273            CHECK_INTERFACE(IAudioFlinger, data, reply);
1274            bool isLowRamDevice = data.readInt32() != 0;
1275            reply->writeInt32(setLowRamDevice(isLowRamDevice));
1276            return NO_ERROR;
1277        } break;
1278        case LIST_AUDIO_PORTS: {
1279            CHECK_INTERFACE(IAudioFlinger, data, reply);
1280            unsigned int num_ports = data.readInt32();
1281            struct audio_port *ports =
1282                    (struct audio_port *)calloc(num_ports,
1283                                                           sizeof(struct audio_port));
1284            status_t status = listAudioPorts(&num_ports, ports);
1285            reply->writeInt32(status);
1286            if (status == NO_ERROR) {
1287                reply->writeInt32(num_ports);
1288                reply->write(&ports, num_ports * sizeof(struct audio_port));
1289            }
1290            free(ports);
1291            return NO_ERROR;
1292        } break;
1293        case GET_AUDIO_PORT: {
1294            CHECK_INTERFACE(IAudioFlinger, data, reply);
1295            struct audio_port port;
1296            data.read(&port, sizeof(struct audio_port));
1297            status_t status = getAudioPort(&port);
1298            reply->writeInt32(status);
1299            if (status == NO_ERROR) {
1300                reply->write(&port, sizeof(struct audio_port));
1301            }
1302            return NO_ERROR;
1303        } break;
1304        case CREATE_AUDIO_PATCH: {
1305            CHECK_INTERFACE(IAudioFlinger, data, reply);
1306            struct audio_patch patch;
1307            data.read(&patch, sizeof(struct audio_patch));
1308            audio_patch_handle_t handle;
1309            data.read(&handle, sizeof(audio_patch_handle_t));
1310            status_t status = createAudioPatch(&patch, &handle);
1311            reply->writeInt32(status);
1312            if (status == NO_ERROR) {
1313                reply->write(&handle, sizeof(audio_patch_handle_t));
1314            }
1315            return NO_ERROR;
1316        } break;
1317        case RELEASE_AUDIO_PATCH: {
1318            CHECK_INTERFACE(IAudioFlinger, data, reply);
1319            audio_patch_handle_t handle;
1320            data.read(&handle, sizeof(audio_patch_handle_t));
1321            status_t status = releaseAudioPatch(handle);
1322            reply->writeInt32(status);
1323            return NO_ERROR;
1324        } break;
1325        case LIST_AUDIO_PATCHES: {
1326            CHECK_INTERFACE(IAudioFlinger, data, reply);
1327            unsigned int num_patches = data.readInt32();
1328            struct audio_patch *patches =
1329                    (struct audio_patch *)calloc(num_patches,
1330                                                 sizeof(struct audio_patch));
1331            status_t status = listAudioPatches(&num_patches, patches);
1332            reply->writeInt32(status);
1333            if (status == NO_ERROR) {
1334                reply->writeInt32(num_patches);
1335                reply->write(&patches, num_patches * sizeof(struct audio_patch));
1336            }
1337            free(patches);
1338            return NO_ERROR;
1339        } break;
1340        case SET_AUDIO_PORT_CONFIG: {
1341            CHECK_INTERFACE(IAudioFlinger, data, reply);
1342            struct audio_port_config config;
1343            data.read(&config, sizeof(struct audio_port_config));
1344            status_t status = setAudioPortConfig(&config);
1345            reply->writeInt32(status);
1346            return NO_ERROR;
1347        } break;
1348        default:
1349            return BBinder::onTransact(code, data, reply, flags);
1350    }
1351}
1352
1353// ----------------------------------------------------------------------------
1354
1355}; // namespace android
1356