1 /*
2  **
3  ** Copyright 2008, 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_NDEBUG 0
19 #define LOG_TAG "IMediaRecorder"
20 
21 #include <inttypes.h>
22 #include <unistd.h>
23 
24 #include <utils/Log.h>
25 #include <binder/Parcel.h>
26 #include <camera/android/hardware/ICamera.h>
27 #include <camera/ICameraRecordingProxy.h>
28 #include <media/IMediaRecorderClient.h>
29 #include <media/IMediaRecorder.h>
30 #include <gui/Surface.h>
31 #include <gui/IGraphicBufferProducer.h>
32 #include <media/stagefright/PersistentSurface.h>
33 
34 namespace android {
35 
36 enum {
37     RELEASE = IBinder::FIRST_CALL_TRANSACTION,
38     INIT,
39     CLOSE,
40     SET_INPUT_SURFACE,
41     QUERY_SURFACE_MEDIASOURCE,
42     RESET,
43     STOP,
44     START,
45     PREPARE,
46     GET_MAX_AMPLITUDE,
47     SET_VIDEO_SOURCE,
48     SET_AUDIO_SOURCE,
49     SET_OUTPUT_FORMAT,
50     SET_VIDEO_ENCODER,
51     SET_AUDIO_ENCODER,
52     SET_OUTPUT_FILE_FD,
53     SET_NEXT_OUTPUT_FILE_FD,
54     SET_VIDEO_SIZE,
55     SET_VIDEO_FRAMERATE,
56     SET_PARAMETERS,
57     SET_PREVIEW_SURFACE,
58     SET_CAMERA,
59     SET_LISTENER,
60     SET_CLIENT_NAME,
61     PAUSE,
62     RESUME,
63     GET_METRICS,
64     SET_INPUT_DEVICE,
65     GET_ROUTED_DEVICE_ID,
66     ENABLE_AUDIO_DEVICE_CALLBACK,
67     GET_ACTIVE_MICROPHONES,
68 
69 };
70 
71 class BpMediaRecorder: public BpInterface<IMediaRecorder>
72 {
73 public:
BpMediaRecorder(const sp<IBinder> & impl)74     explicit BpMediaRecorder(const sp<IBinder>& impl)
75     : BpInterface<IMediaRecorder>(impl)
76     {
77     }
78 
setCamera(const sp<hardware::ICamera> & camera,const sp<ICameraRecordingProxy> & proxy)79     status_t setCamera(const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy)
80     {
81         ALOGV("setCamera(%p,%p)", camera.get(), proxy.get());
82         Parcel data, reply;
83         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
84         data.writeStrongBinder(IInterface::asBinder(camera));
85         data.writeStrongBinder(IInterface::asBinder(proxy));
86         remote()->transact(SET_CAMERA, data, &reply);
87         return reply.readInt32();
88     }
89 
setInputSurface(const sp<PersistentSurface> & surface)90     status_t setInputSurface(const sp<PersistentSurface>& surface)
91     {
92         ALOGV("setInputSurface(%p)", surface.get());
93         Parcel data, reply;
94         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
95         surface->writeToParcel(&data);
96         remote()->transact(SET_INPUT_SURFACE, data, &reply);
97         return reply.readInt32();
98     }
99 
querySurfaceMediaSource()100     sp<IGraphicBufferProducer> querySurfaceMediaSource()
101     {
102         ALOGV("Query SurfaceMediaSource");
103         Parcel data, reply;
104         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
105         remote()->transact(QUERY_SURFACE_MEDIASOURCE, data, &reply);
106         int returnedNull = reply.readInt32();
107         if (returnedNull) {
108             return NULL;
109         }
110         return interface_cast<IGraphicBufferProducer>(reply.readStrongBinder());
111     }
112 
setPreviewSurface(const sp<IGraphicBufferProducer> & surface)113     status_t setPreviewSurface(const sp<IGraphicBufferProducer>& surface)
114     {
115         ALOGV("setPreviewSurface(%p)", surface.get());
116         Parcel data, reply;
117         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
118         data.writeStrongBinder(IInterface::asBinder(surface));
119         remote()->transact(SET_PREVIEW_SURFACE, data, &reply);
120         return reply.readInt32();
121     }
122 
init()123     status_t init()
124     {
125         ALOGV("init");
126         Parcel data, reply;
127         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
128         remote()->transact(INIT, data, &reply);
129         return reply.readInt32();
130     }
131 
setVideoSource(int vs)132     status_t setVideoSource(int vs)
133     {
134         ALOGV("setVideoSource(%d)", vs);
135         Parcel data, reply;
136         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
137         data.writeInt32(vs);
138         remote()->transact(SET_VIDEO_SOURCE, data, &reply);
139         return reply.readInt32();
140     }
141 
setAudioSource(int as)142     status_t setAudioSource(int as)
143     {
144         ALOGV("setAudioSource(%d)", as);
145         Parcel data, reply;
146         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
147         data.writeInt32(as);
148         remote()->transact(SET_AUDIO_SOURCE, data, &reply);
149         return reply.readInt32();
150     }
151 
setOutputFormat(int of)152     status_t setOutputFormat(int of)
153     {
154         ALOGV("setOutputFormat(%d)", of);
155         Parcel data, reply;
156         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
157         data.writeInt32(of);
158         remote()->transact(SET_OUTPUT_FORMAT, data, &reply);
159         return reply.readInt32();
160     }
161 
setVideoEncoder(int ve)162     status_t setVideoEncoder(int ve)
163     {
164         ALOGV("setVideoEncoder(%d)", ve);
165         Parcel data, reply;
166         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
167         data.writeInt32(ve);
168         remote()->transact(SET_VIDEO_ENCODER, data, &reply);
169         return reply.readInt32();
170     }
171 
setAudioEncoder(int ae)172     status_t setAudioEncoder(int ae)
173     {
174         ALOGV("setAudioEncoder(%d)", ae);
175         Parcel data, reply;
176         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
177         data.writeInt32(ae);
178         remote()->transact(SET_AUDIO_ENCODER, data, &reply);
179         return reply.readInt32();
180     }
181 
setOutputFile(int fd)182     status_t setOutputFile(int fd) {
183         ALOGV("setOutputFile(%d)", fd);
184         Parcel data, reply;
185         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
186         data.writeFileDescriptor(fd);
187         remote()->transact(SET_OUTPUT_FILE_FD, data, &reply);
188         return reply.readInt32();
189     }
190 
setNextOutputFile(int fd)191     status_t setNextOutputFile(int fd) {
192         ALOGV("setNextOutputFile(%d)", fd);
193         Parcel data, reply;
194         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
195         data.writeFileDescriptor(fd);
196         remote()->transact(SET_NEXT_OUTPUT_FILE_FD, data, &reply);
197         return reply.readInt32();
198     }
199 
setVideoSize(int width,int height)200     status_t setVideoSize(int width, int height)
201     {
202         ALOGV("setVideoSize(%dx%d)", width, height);
203         Parcel data, reply;
204         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
205         data.writeInt32(width);
206         data.writeInt32(height);
207         remote()->transact(SET_VIDEO_SIZE, data, &reply);
208         return reply.readInt32();
209     }
210 
setVideoFrameRate(int frames_per_second)211     status_t setVideoFrameRate(int frames_per_second)
212     {
213         ALOGV("setVideoFrameRate(%d)", frames_per_second);
214         Parcel data, reply;
215         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
216         data.writeInt32(frames_per_second);
217         remote()->transact(SET_VIDEO_FRAMERATE, data, &reply);
218         return reply.readInt32();
219     }
220 
setParameters(const String8 & params)221     status_t setParameters(const String8& params)
222     {
223         ALOGV("setParameter(%s)", params.string());
224         Parcel data, reply;
225         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
226         data.writeString8(params);
227         remote()->transact(SET_PARAMETERS, data, &reply);
228         return reply.readInt32();
229     }
230 
setListener(const sp<IMediaRecorderClient> & listener)231     status_t setListener(const sp<IMediaRecorderClient>& listener)
232     {
233         ALOGV("setListener(%p)", listener.get());
234         Parcel data, reply;
235         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
236         data.writeStrongBinder(IInterface::asBinder(listener));
237         remote()->transact(SET_LISTENER, data, &reply);
238         return reply.readInt32();
239     }
240 
setClientName(const String16 & clientName)241     status_t setClientName(const String16& clientName)
242     {
243         ALOGV("setClientName(%s)", String8(clientName).string());
244         Parcel data, reply;
245         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
246         data.writeString16(clientName);
247         remote()->transact(SET_CLIENT_NAME, data, &reply);
248         return reply.readInt32();
249     }
250 
prepare()251     status_t prepare()
252     {
253         ALOGV("prepare");
254         Parcel data, reply;
255         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
256         remote()->transact(PREPARE, data, &reply);
257         return reply.readInt32();
258     }
259 
getMaxAmplitude(int * max)260     status_t getMaxAmplitude(int* max)
261     {
262         ALOGV("getMaxAmplitude");
263         Parcel data, reply;
264         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
265         remote()->transact(GET_MAX_AMPLITUDE, data, &reply);
266         *max = reply.readInt32();
267         return reply.readInt32();
268     }
269 
getMetrics(Parcel * reply)270     status_t getMetrics(Parcel* reply)
271     {
272         ALOGV("getMetrics");
273         Parcel data;
274         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
275         status_t ret = remote()->transact(GET_METRICS, data, reply);
276         if (ret == NO_ERROR) {
277             return OK;
278         }
279         return UNKNOWN_ERROR;
280     }
281 
start()282     status_t start()
283     {
284         ALOGV("start");
285         Parcel data, reply;
286         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
287         remote()->transact(START, data, &reply);
288         return reply.readInt32();
289     }
290 
stop()291     status_t stop()
292     {
293         ALOGV("stop");
294         Parcel data, reply;
295         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
296         remote()->transact(STOP, data, &reply);
297         return reply.readInt32();
298     }
299 
reset()300     status_t reset()
301     {
302         ALOGV("reset");
303         Parcel data, reply;
304         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
305         remote()->transact(RESET, data, &reply);
306         return reply.readInt32();
307     }
308 
pause()309     status_t pause()
310     {
311         ALOGV("pause");
312         Parcel data, reply;
313         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
314         remote()->transact(PAUSE, data, &reply);
315         return reply.readInt32();
316     }
317 
resume()318     status_t resume()
319     {
320         ALOGV("resume");
321         Parcel data, reply;
322         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
323         remote()->transact(RESUME, data, &reply);
324         return reply.readInt32();
325     }
326 
close()327     status_t close()
328     {
329         ALOGV("close");
330         Parcel data, reply;
331         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
332         remote()->transact(CLOSE, data, &reply);
333         return reply.readInt32();
334     }
335 
release()336     status_t release()
337     {
338         ALOGV("release");
339         Parcel data, reply;
340         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
341         remote()->transact(RELEASE, data, &reply);
342         return reply.readInt32();
343     }
344 
setInputDevice(audio_port_handle_t deviceId)345     status_t setInputDevice(audio_port_handle_t deviceId)
346     {
347         ALOGV("setInputDevice");
348         Parcel data, reply;
349         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
350         data.writeInt32(deviceId);
351 
352         status_t status = remote()->transact(SET_INPUT_DEVICE, data, &reply);
353         if (status != OK) {
354             ALOGE("setInputDevice binder call failed: %d", status);
355             return status;
356         }
357         return reply.readInt32();;
358     }
359 
getRoutedDeviceId(audio_port_handle_t * deviceId)360     audio_port_handle_t getRoutedDeviceId(audio_port_handle_t *deviceId)
361     {
362         ALOGV("getRoutedDeviceId");
363         Parcel data, reply;
364         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
365 
366         status_t status = remote()->transact(GET_ROUTED_DEVICE_ID, data, &reply);
367         if (status != OK) {
368             ALOGE("getRoutedDeviceid binder call failed: %d", status);
369             *deviceId = AUDIO_PORT_HANDLE_NONE;
370             return status;
371         }
372 
373         status = reply.readInt32();
374         if (status != NO_ERROR) {
375             *deviceId = AUDIO_PORT_HANDLE_NONE;
376         } else {
377             *deviceId = reply.readInt32();
378         }
379         return status;
380     }
381 
enableAudioDeviceCallback(bool enabled)382     status_t enableAudioDeviceCallback(bool enabled)
383     {
384         ALOGV("enableAudioDeviceCallback");
385         Parcel data, reply;
386         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
387         data.writeBool(enabled);
388         status_t status = remote()->transact(ENABLE_AUDIO_DEVICE_CALLBACK, data, &reply);
389         if (status != OK) {
390             ALOGE("enableAudioDeviceCallback binder call failed: %d, %d", enabled, status);
391             return status;
392         }
393         return reply.readInt32();
394     }
395 
getActiveMicrophones(std::vector<media::MicrophoneInfo> * activeMicrophones)396     status_t getActiveMicrophones(std::vector<media::MicrophoneInfo>* activeMicrophones)
397     {
398         ALOGV("getActiveMicrophones");
399         Parcel data, reply;
400         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
401         status_t status = remote()->transact(GET_ACTIVE_MICROPHONES, data, &reply);
402         if (status != OK
403                 || (status = (status_t)reply.readInt32()) != NO_ERROR) {
404             return status;
405         }
406         status = reply.readParcelableVector(activeMicrophones);
407         return status;
408     }
409 
410 };
411 
412 IMPLEMENT_META_INTERFACE(MediaRecorder, "android.media.IMediaRecorder");
413 
414 // ----------------------------------------------------------------------
415 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)416 status_t BnMediaRecorder::onTransact(
417                                      uint32_t code, const Parcel& data, Parcel* reply,
418                                      uint32_t flags)
419 {
420     switch (code) {
421         case RELEASE: {
422             ALOGV("RELEASE");
423             CHECK_INTERFACE(IMediaRecorder, data, reply);
424             reply->writeInt32(release());
425             return NO_ERROR;
426         } break;
427         case INIT: {
428             ALOGV("INIT");
429             CHECK_INTERFACE(IMediaRecorder, data, reply);
430             reply->writeInt32(init());
431             return NO_ERROR;
432         } break;
433         case CLOSE: {
434             ALOGV("CLOSE");
435             CHECK_INTERFACE(IMediaRecorder, data, reply);
436             reply->writeInt32(close());
437             return NO_ERROR;
438         } break;
439         case RESET: {
440             ALOGV("RESET");
441             CHECK_INTERFACE(IMediaRecorder, data, reply);
442             reply->writeInt32(reset());
443             return NO_ERROR;
444         } break;
445         case STOP: {
446             ALOGV("STOP");
447             CHECK_INTERFACE(IMediaRecorder, data, reply);
448             reply->writeInt32(stop());
449             return NO_ERROR;
450         } break;
451         case START: {
452             ALOGV("START");
453             CHECK_INTERFACE(IMediaRecorder, data, reply);
454             reply->writeInt32(start());
455             return NO_ERROR;
456         } break;
457         case PAUSE: {
458             ALOGV("PAUSE");
459             CHECK_INTERFACE(IMediaRecorder, data, reply);
460             reply->writeInt32(pause());
461             return NO_ERROR;
462         } break;
463         case RESUME: {
464             ALOGV("RESUME");
465             CHECK_INTERFACE(IMediaRecorder, data, reply);
466             reply->writeInt32(resume());
467             return NO_ERROR;
468         } break;
469         case PREPARE: {
470             ALOGV("PREPARE");
471             CHECK_INTERFACE(IMediaRecorder, data, reply);
472             reply->writeInt32(prepare());
473             return NO_ERROR;
474         } break;
475         case GET_MAX_AMPLITUDE: {
476             ALOGV("GET_MAX_AMPLITUDE");
477             CHECK_INTERFACE(IMediaRecorder, data, reply);
478             int max = 0;
479             status_t ret = getMaxAmplitude(&max);
480             reply->writeInt32(max);
481             reply->writeInt32(ret);
482             return NO_ERROR;
483         } break;
484         case GET_METRICS: {
485             ALOGV("GET_METRICS");
486             status_t ret = getMetrics(reply);
487             return ret;
488         } break;
489         case SET_VIDEO_SOURCE: {
490             ALOGV("SET_VIDEO_SOURCE");
491             CHECK_INTERFACE(IMediaRecorder, data, reply);
492             int vs = data.readInt32();
493             reply->writeInt32(setVideoSource(vs));
494             return NO_ERROR;
495         } break;
496         case SET_AUDIO_SOURCE: {
497             ALOGV("SET_AUDIO_SOURCE");
498             CHECK_INTERFACE(IMediaRecorder, data, reply);
499             int as = data.readInt32();
500             reply->writeInt32(setAudioSource(as));
501             return NO_ERROR;
502         } break;
503         case SET_OUTPUT_FORMAT: {
504             ALOGV("SET_OUTPUT_FORMAT");
505             CHECK_INTERFACE(IMediaRecorder, data, reply);
506             int of = data.readInt32();
507             reply->writeInt32(setOutputFormat(of));
508             return NO_ERROR;
509         } break;
510         case SET_VIDEO_ENCODER: {
511             ALOGV("SET_VIDEO_ENCODER");
512             CHECK_INTERFACE(IMediaRecorder, data, reply);
513             int ve = data.readInt32();
514             reply->writeInt32(setVideoEncoder(ve));
515             return NO_ERROR;
516         } break;
517         case SET_AUDIO_ENCODER: {
518             ALOGV("SET_AUDIO_ENCODER");
519             CHECK_INTERFACE(IMediaRecorder, data, reply);
520             int ae = data.readInt32();
521             reply->writeInt32(setAudioEncoder(ae));
522             return NO_ERROR;
523 
524         } break;
525         case SET_OUTPUT_FILE_FD: {
526             ALOGV("SET_OUTPUT_FILE_FD");
527             CHECK_INTERFACE(IMediaRecorder, data, reply);
528             int fd = dup(data.readFileDescriptor());
529             reply->writeInt32(setOutputFile(fd));
530             ::close(fd);
531             return NO_ERROR;
532         } break;
533         case SET_NEXT_OUTPUT_FILE_FD: {
534             ALOGV("SET_NEXT_OUTPUT_FILE_FD");
535             CHECK_INTERFACE(IMediaRecorder, data, reply);
536             int fd = dup(data.readFileDescriptor());
537             reply->writeInt32(setNextOutputFile(fd));
538             ::close(fd);
539             return NO_ERROR;
540         } break;
541         case SET_VIDEO_SIZE: {
542             ALOGV("SET_VIDEO_SIZE");
543             CHECK_INTERFACE(IMediaRecorder, data, reply);
544             int width = data.readInt32();
545             int height = data.readInt32();
546             reply->writeInt32(setVideoSize(width, height));
547             return NO_ERROR;
548         } break;
549         case SET_VIDEO_FRAMERATE: {
550             ALOGV("SET_VIDEO_FRAMERATE");
551             CHECK_INTERFACE(IMediaRecorder, data, reply);
552             int frames_per_second = data.readInt32();
553             reply->writeInt32(setVideoFrameRate(frames_per_second));
554             return NO_ERROR;
555         } break;
556         case SET_PARAMETERS: {
557             ALOGV("SET_PARAMETER");
558             CHECK_INTERFACE(IMediaRecorder, data, reply);
559             reply->writeInt32(setParameters(data.readString8()));
560             return NO_ERROR;
561         } break;
562         case SET_LISTENER: {
563             ALOGV("SET_LISTENER");
564             CHECK_INTERFACE(IMediaRecorder, data, reply);
565             sp<IMediaRecorderClient> listener =
566                 interface_cast<IMediaRecorderClient>(data.readStrongBinder());
567             reply->writeInt32(setListener(listener));
568             return NO_ERROR;
569         } break;
570         case SET_CLIENT_NAME: {
571             ALOGV("SET_CLIENT_NAME");
572             CHECK_INTERFACE(IMediaRecorder, data, reply);
573             reply->writeInt32(setClientName(data.readString16()));
574             return NO_ERROR;
575         }
576         case SET_PREVIEW_SURFACE: {
577             ALOGV("SET_PREVIEW_SURFACE");
578             CHECK_INTERFACE(IMediaRecorder, data, reply);
579             sp<IGraphicBufferProducer> surface = interface_cast<IGraphicBufferProducer>(
580                     data.readStrongBinder());
581             reply->writeInt32(setPreviewSurface(surface));
582             return NO_ERROR;
583         } break;
584         case SET_CAMERA: {
585             ALOGV("SET_CAMERA");
586             CHECK_INTERFACE(IMediaRecorder, data, reply);
587             sp<hardware::ICamera> camera =
588                     interface_cast<hardware::ICamera>(data.readStrongBinder());
589             sp<ICameraRecordingProxy> proxy =
590                     interface_cast<ICameraRecordingProxy>(data.readStrongBinder());
591             reply->writeInt32(setCamera(camera, proxy));
592             return NO_ERROR;
593         } break;
594         case SET_INPUT_SURFACE: {
595             ALOGV("SET_INPUT_SURFACE");
596             CHECK_INTERFACE(IMediaRecorder, data, reply);
597             sp<PersistentSurface> surface = new PersistentSurface();
598             surface->readFromParcel(&data);
599             reply->writeInt32(setInputSurface(surface));
600             return NO_ERROR;
601         } break;
602         case QUERY_SURFACE_MEDIASOURCE: {
603             ALOGV("QUERY_SURFACE_MEDIASOURCE");
604             CHECK_INTERFACE(IMediaRecorder, data, reply);
605             // call the mediaserver side to create
606             // a surfacemediasource
607             sp<IGraphicBufferProducer> surfaceMediaSource = querySurfaceMediaSource();
608             // The mediaserver might have failed to create a source
609             int returnedNull= (surfaceMediaSource == NULL) ? 1 : 0 ;
610             reply->writeInt32(returnedNull);
611             if (!returnedNull) {
612                 reply->writeStrongBinder(IInterface::asBinder(surfaceMediaSource));
613             }
614             return NO_ERROR;
615         } break;
616         case SET_INPUT_DEVICE: {
617             ALOGV("SET_INPUT_DEVICE");
618             CHECK_INTERFACE(IMediaRecorder, data, reply);
619             audio_port_handle_t deviceId;
620             status_t status = data.readInt32(&deviceId);
621             if (status == NO_ERROR) {
622                 reply->writeInt32(setInputDevice(deviceId));
623             } else {
624                 reply->writeInt32(BAD_VALUE);
625             }
626             return NO_ERROR;
627         } break;
628         case GET_ROUTED_DEVICE_ID: {
629             ALOGV("GET_ROUTED_DEVICE_ID");
630             CHECK_INTERFACE(IMediaRecorder, data, reply);
631             audio_port_handle_t deviceId;
632             status_t status = getRoutedDeviceId(&deviceId);
633             reply->writeInt32(status);
634             if (status == NO_ERROR) {
635                 reply->writeInt32(deviceId);
636             }
637             return NO_ERROR;
638         } break;
639         case ENABLE_AUDIO_DEVICE_CALLBACK: {
640             ALOGV("ENABLE_AUDIO_DEVICE_CALLBACK");
641             CHECK_INTERFACE(IMediaRecorder, data, reply);
642             bool enabled;
643             status_t status = data.readBool(&enabled);
644             if (status == NO_ERROR) {
645                 reply->writeInt32(enableAudioDeviceCallback(enabled));
646             } else {
647                 reply->writeInt32(BAD_VALUE);
648             }
649             return NO_ERROR;
650         } break;
651         case GET_ACTIVE_MICROPHONES: {
652             ALOGV("GET_ACTIVE_MICROPHONES");
653             CHECK_INTERFACE(IMediaRecorder, data, reply);
654             std::vector<media::MicrophoneInfo> activeMicrophones;
655             status_t status = getActiveMicrophones(&activeMicrophones);
656             reply->writeInt32(status);
657             if (status != NO_ERROR) {
658                 return NO_ERROR;
659             }
660             reply->writeParcelableVector(activeMicrophones);
661             return NO_ERROR;
662 
663         }
664         default:
665             return BBinder::onTransact(code, data, reply, flags);
666     }
667 }
668 
669 // ----------------------------------------------------------------------------
670 
671 } // namespace android
672