blob: 474381bc68d52c8cb7064bb63f72e8359af92f77 [file] [log] [blame]
The Android Open Source Project2729ea92008-10-21 07:00:00 -07001/* //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 SET_MASTER_VOLUME,
38 SET_MASTER_MUTE,
39 MASTER_VOLUME,
40 MASTER_MUTE,
41 SET_STREAM_VOLUME,
42 SET_STREAM_MUTE,
43 STREAM_VOLUME,
44 STREAM_MUTE,
45 SET_MODE,
46 GET_MODE,
47 SET_ROUTING,
48 GET_ROUTING,
49 SET_MIC_MUTE,
50 GET_MIC_MUTE,
51 IS_MUSIC_ACTIVE,
52 SET_PARAMETER,
53};
54
55class BpAudioFlinger : public BpInterface<IAudioFlinger>
56{
57public:
58 BpAudioFlinger(const sp<IBinder>& impl)
59 : BpInterface<IAudioFlinger>(impl)
60 {
61 }
62
63 virtual sp<IAudioTrack> createTrack(
64 pid_t pid,
65 int streamType,
66 uint32_t sampleRate,
67 int format,
68 int channelCount,
69 int bufferCount,
70 uint32_t flags)
71 {
72 Parcel data, reply;
73 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
74 data.writeInt32(pid);
75 data.writeInt32(streamType);
76 data.writeInt32(sampleRate);
77 data.writeInt32(format);
78 data.writeInt32(channelCount);
79 data.writeInt32(bufferCount);
80 data.writeInt32(flags);
81 status_t status = remote()->transact(CREATE_TRACK, data, &reply);
82 if ( status != NO_ERROR) {
83 LOGE("createTrack error: %s", strerror(-status));
84 }
85
86 return interface_cast<IAudioTrack>(reply.readStrongBinder());
87 }
88
89 virtual sp<IAudioRecord> openRecord(
90 pid_t pid,
91 int streamType,
92 uint32_t sampleRate,
93 int format,
94 int channelCount,
95 int bufferCount,
96 uint32_t flags)
97 {
98 Parcel data, reply;
99 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
100 data.writeInt32(pid);
101 data.writeInt32(streamType);
102 data.writeInt32(sampleRate);
103 data.writeInt32(format);
104 data.writeInt32(channelCount);
105 data.writeInt32(bufferCount);
106 data.writeInt32(flags);
107 remote()->transact(OPEN_RECORD, data, &reply);
108 return interface_cast<IAudioRecord>(reply.readStrongBinder());
109 }
110
111 virtual uint32_t sampleRate() const
112 {
113 Parcel data, reply;
114 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
115 remote()->transact(SAMPLE_RATE, data, &reply);
116 return reply.readInt32();
117 }
118
119 virtual int channelCount() const
120 {
121 Parcel data, reply;
122 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
123 remote()->transact(CHANNEL_COUNT, data, &reply);
124 return reply.readInt32();
125 }
126
127 virtual int format() const
128 {
129 Parcel data, reply;
130 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
131 remote()->transact(FORMAT, data, &reply);
132 return reply.readInt32();
133 }
134
135 virtual size_t frameCount() const
136 {
137 Parcel data, reply;
138 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
139 remote()->transact(FRAME_COUNT, data, &reply);
140 return reply.readInt32();
141 }
142
143 virtual status_t setMasterVolume(float value)
144 {
145 Parcel data, reply;
146 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
147 data.writeFloat(value);
148 remote()->transact(SET_MASTER_VOLUME, data, &reply);
149 return reply.readInt32();
150 }
151
152 virtual status_t setMasterMute(bool muted)
153 {
154 Parcel data, reply;
155 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
156 data.writeInt32(muted);
157 remote()->transact(SET_MASTER_MUTE, data, &reply);
158 return reply.readInt32();
159 }
160
161 virtual float masterVolume() const
162 {
163 Parcel data, reply;
164 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
165 remote()->transact(MASTER_VOLUME, data, &reply);
166 return reply.readFloat();
167 }
168
169 virtual bool masterMute() const
170 {
171 Parcel data, reply;
172 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
173 remote()->transact(MASTER_MUTE, data, &reply);
174 return reply.readInt32();
175 }
176
177 virtual status_t setStreamVolume(int stream, float value)
178 {
179 Parcel data, reply;
180 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
181 data.writeInt32(stream);
182 data.writeFloat(value);
183 remote()->transact(SET_STREAM_VOLUME, data, &reply);
184 return reply.readInt32();
185 }
186
187 virtual status_t setStreamMute(int stream, bool muted)
188 {
189 Parcel data, reply;
190 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
191 data.writeInt32(stream);
192 data.writeInt32(muted);
193 remote()->transact(SET_STREAM_MUTE, data, &reply);
194 return reply.readInt32();
195 }
196
197 virtual float streamVolume(int stream) const
198 {
199 Parcel data, reply;
200 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
201 data.writeInt32(stream);
202 remote()->transact(STREAM_VOLUME, data, &reply);
203 return reply.readFloat();
204 }
205
206 virtual bool streamMute(int stream) const
207 {
208 Parcel data, reply;
209 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
210 data.writeInt32(stream);
211 remote()->transact(STREAM_MUTE, data, &reply);
212 return reply.readInt32();
213 }
214
215 virtual status_t setRouting(int mode, uint32_t routes, uint32_t mask)
216 {
217 Parcel data, reply;
218 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
219 data.writeInt32(mode);
220 data.writeInt32(routes);
221 data.writeInt32(mask);
222 remote()->transact(SET_ROUTING, data, &reply);
223 return reply.readInt32();
224 }
225
226 virtual uint32_t getRouting(int mode) const
227 {
228 Parcel data, reply;
229 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
230 data.writeInt32(mode);
231 remote()->transact(GET_ROUTING, data, &reply);
232 return reply.readInt32();
233 }
234
235 virtual status_t setMode(int mode)
236 {
237 Parcel data, reply;
238 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
239 data.writeInt32(mode);
240 remote()->transact(SET_MODE, data, &reply);
241 return reply.readInt32();
242 }
243
244 virtual int getMode() const
245 {
246 Parcel data, reply;
247 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
248 remote()->transact(GET_MODE, data, &reply);
249 return reply.readInt32();
250 }
251
252 virtual status_t setMicMute(bool state)
253 {
254 Parcel data, reply;
255 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
256 data.writeInt32(state);
257 remote()->transact(SET_MIC_MUTE, data, &reply);
258 return reply.readInt32();
259 }
260
261 virtual bool getMicMute() const
262 {
263 Parcel data, reply;
264 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
265 remote()->transact(GET_MIC_MUTE, data, &reply);
266 return reply.readInt32();
267 }
268
269 virtual bool isMusicActive() const
270 {
271 Parcel data, reply;
272 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
273 remote()->transact(IS_MUSIC_ACTIVE, data, &reply);
274 return reply.readInt32();
275 }
276
277 virtual status_t setParameter(const char* key, const char* value)
278 {
279 Parcel data, reply;
280 data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
281 data.writeCString(key);
282 data.writeCString(value);
283 remote()->transact(SET_PARAMETER, data, &reply);
284 return reply.readInt32();
285 }
286};
287
288IMPLEMENT_META_INTERFACE(AudioFlinger, "android.media.IAudioFlinger");
289
290// ----------------------------------------------------------------------
291
292#define CHECK_INTERFACE(interface, data, reply) \
293 do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
294 LOGW("Call incorrectly routed to " #interface); \
295 return PERMISSION_DENIED; \
296 } } while (0)
297
298status_t BnAudioFlinger::onTransact(
299 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
300{
301 switch(code) {
302 case CREATE_TRACK: {
303 CHECK_INTERFACE(IAudioFlinger, data, reply);
304 pid_t pid = data.readInt32();
305 int streamType = data.readInt32();
306 uint32_t sampleRate = data.readInt32();
307 int format = data.readInt32();
308 int channelCount = data.readInt32();
309 size_t bufferCount = data.readInt32();
310 uint32_t flags = data.readInt32();
311 sp<IAudioTrack> track = createTrack(pid,
312 streamType, sampleRate, format,
313 channelCount, bufferCount, flags);
314 reply->writeStrongBinder(track->asBinder());
315 return NO_ERROR;
316 } break;
317 case OPEN_RECORD: {
318 CHECK_INTERFACE(IAudioFlinger, data, reply);
319 pid_t pid = data.readInt32();
320 int streamType = data.readInt32();
321 uint32_t sampleRate = data.readInt32();
322 int format = data.readInt32();
323 int channelCount = data.readInt32();
324 size_t bufferCount = data.readInt32();
325 uint32_t flags = data.readInt32();
326 sp<IAudioRecord> record = openRecord(pid, streamType,
327 sampleRate, format, channelCount, bufferCount, flags);
328 reply->writeStrongBinder(record->asBinder());
329 return NO_ERROR;
330 } break;
331 case SAMPLE_RATE: {
332 CHECK_INTERFACE(IAudioFlinger, data, reply);
333 reply->writeInt32( sampleRate() );
334 return NO_ERROR;
335 } break;
336 case CHANNEL_COUNT: {
337 CHECK_INTERFACE(IAudioFlinger, data, reply);
338 reply->writeInt32( channelCount() );
339 return NO_ERROR;
340 } break;
341 case FORMAT: {
342 CHECK_INTERFACE(IAudioFlinger, data, reply);
343 reply->writeInt32( format() );
344 return NO_ERROR;
345 } break;
346 case FRAME_COUNT: {
347 CHECK_INTERFACE(IAudioFlinger, data, reply);
348 reply->writeInt32( frameCount() );
349 return NO_ERROR;
350 } break;
351 case SET_MASTER_VOLUME: {
352 CHECK_INTERFACE(IAudioFlinger, data, reply);
353 reply->writeInt32( setMasterVolume(data.readFloat()) );
354 return NO_ERROR;
355 } break;
356 case SET_MASTER_MUTE: {
357 CHECK_INTERFACE(IAudioFlinger, data, reply);
358 reply->writeInt32( setMasterMute(data.readInt32()) );
359 return NO_ERROR;
360 } break;
361 case MASTER_VOLUME: {
362 CHECK_INTERFACE(IAudioFlinger, data, reply);
363 reply->writeFloat( masterVolume() );
364 return NO_ERROR;
365 } break;
366 case MASTER_MUTE: {
367 CHECK_INTERFACE(IAudioFlinger, data, reply);
368 reply->writeInt32( masterMute() );
369 return NO_ERROR;
370 } break;
371 case SET_STREAM_VOLUME: {
372 CHECK_INTERFACE(IAudioFlinger, data, reply);
373 int stream = data.readInt32();
374 reply->writeInt32( setStreamVolume(stream, data.readFloat()) );
375 return NO_ERROR;
376 } break;
377 case SET_STREAM_MUTE: {
378 CHECK_INTERFACE(IAudioFlinger, data, reply);
379 int stream = data.readInt32();
380 reply->writeInt32( setStreamMute(stream, data.readInt32()) );
381 return NO_ERROR;
382 } break;
383 case STREAM_VOLUME: {
384 CHECK_INTERFACE(IAudioFlinger, data, reply);
385 int stream = data.readInt32();
386 reply->writeFloat( streamVolume(stream) );
387 return NO_ERROR;
388 } break;
389 case STREAM_MUTE: {
390 CHECK_INTERFACE(IAudioFlinger, data, reply);
391 int stream = data.readInt32();
392 reply->writeInt32( streamMute(stream) );
393 return NO_ERROR;
394 } break;
395 case SET_ROUTING: {
396 CHECK_INTERFACE(IAudioFlinger, data, reply);
397 int mode = data.readInt32();
398 uint32_t routes = data.readInt32();
399 uint32_t mask = data.readInt32();
400 reply->writeInt32( setRouting(mode, routes, mask) );
401 return NO_ERROR;
402 } break;
403 case GET_ROUTING: {
404 CHECK_INTERFACE(IAudioFlinger, data, reply);
405 int mode = data.readInt32();
406 reply->writeInt32( getRouting(mode) );
407 return NO_ERROR;
408 } break;
409 case SET_MODE: {
410 CHECK_INTERFACE(IAudioFlinger, data, reply);
411 int mode = data.readInt32();
412 reply->writeInt32( setMode(mode) );
413 return NO_ERROR;
414 } break;
415 case GET_MODE: {
416 CHECK_INTERFACE(IAudioFlinger, data, reply);
417 reply->writeInt32( getMode() );
418 return NO_ERROR;
419 } break;
420 case SET_MIC_MUTE: {
421 CHECK_INTERFACE(IAudioFlinger, data, reply);
422 int state = data.readInt32();
423 reply->writeInt32( setMicMute(state) );
424 return NO_ERROR;
425 } break;
426 case GET_MIC_MUTE: {
427 CHECK_INTERFACE(IAudioFlinger, data, reply);
428 reply->writeInt32( getMicMute() );
429 return NO_ERROR;
430 } break;
431 case IS_MUSIC_ACTIVE: {
432 CHECK_INTERFACE(IAudioFlinger, data, reply);
433 reply->writeInt32( isMusicActive() );
434 return NO_ERROR;
435 } break;
436 case SET_PARAMETER: {
437 CHECK_INTERFACE(IAudioFlinger, data, reply);
438 const char *key = data.readCString();
439 const char *value = data.readCString();
440 reply->writeInt32( setParameter(key, value) );
441 return NO_ERROR;
442 } break;
443 default:
444 return BBinder::onTransact(code, data, reply, flags);
445 }
446}
447
448// ----------------------------------------------------------------------------
449
450}; // namespace android