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 
33 namespace android {
34 
35 enum {
36     RELEASE = IBinder::FIRST_CALL_TRANSACTION,
37     INIT,
38     CLOSE,
39     SET_INPUT_SURFACE,
40     QUERY_SURFACE_MEDIASOURCE,
41     RESET,
42     STOP,
43     START,
44     PREPARE,
45     GET_MAX_AMPLITUDE,
46     SET_VIDEO_SOURCE,
47     SET_AUDIO_SOURCE,
48     SET_OUTPUT_FORMAT,
49     SET_VIDEO_ENCODER,
50     SET_AUDIO_ENCODER,
51     SET_OUTPUT_FILE_FD,
52     SET_VIDEO_SIZE,
53     SET_VIDEO_FRAMERATE,
54     SET_PARAMETERS,
55     SET_PREVIEW_SURFACE,
56     SET_CAMERA,
57     SET_LISTENER,
58     SET_CLIENT_NAME,
59     PAUSE,
60     RESUME
61 };
62 
63 class BpMediaRecorder: public BpInterface<IMediaRecorder>
64 {
65 public:
BpMediaRecorder(const sp<IBinder> & impl)66     BpMediaRecorder(const sp<IBinder>& impl)
67     : BpInterface<IMediaRecorder>(impl)
68     {
69     }
70 
setCamera(const sp<hardware::ICamera> & camera,const sp<ICameraRecordingProxy> & proxy)71     status_t setCamera(const sp<hardware::ICamera>& camera, const sp<ICameraRecordingProxy>& proxy)
72     {
73         ALOGV("setCamera(%p,%p)", camera.get(), proxy.get());
74         Parcel data, reply;
75         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
76         data.writeStrongBinder(IInterface::asBinder(camera));
77         data.writeStrongBinder(IInterface::asBinder(proxy));
78         remote()->transact(SET_CAMERA, data, &reply);
79         return reply.readInt32();
80     }
81 
setInputSurface(const sp<IGraphicBufferConsumer> & surface)82     status_t setInputSurface(const sp<IGraphicBufferConsumer>& surface)
83     {
84         ALOGV("setInputSurface(%p)", surface.get());
85         Parcel data, reply;
86         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
87         data.writeStrongBinder(IInterface::asBinder(surface));
88         remote()->transact(SET_INPUT_SURFACE, data, &reply);
89         return reply.readInt32();
90     }
91 
querySurfaceMediaSource()92     sp<IGraphicBufferProducer> querySurfaceMediaSource()
93     {
94         ALOGV("Query SurfaceMediaSource");
95         Parcel data, reply;
96         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
97         remote()->transact(QUERY_SURFACE_MEDIASOURCE, data, &reply);
98         int returnedNull = reply.readInt32();
99         if (returnedNull) {
100             return NULL;
101         }
102         return interface_cast<IGraphicBufferProducer>(reply.readStrongBinder());
103     }
104 
setPreviewSurface(const sp<IGraphicBufferProducer> & surface)105     status_t setPreviewSurface(const sp<IGraphicBufferProducer>& surface)
106     {
107         ALOGV("setPreviewSurface(%p)", surface.get());
108         Parcel data, reply;
109         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
110         data.writeStrongBinder(IInterface::asBinder(surface));
111         remote()->transact(SET_PREVIEW_SURFACE, data, &reply);
112         return reply.readInt32();
113     }
114 
init()115     status_t init()
116     {
117         ALOGV("init");
118         Parcel data, reply;
119         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
120         remote()->transact(INIT, data, &reply);
121         return reply.readInt32();
122     }
123 
setVideoSource(int vs)124     status_t setVideoSource(int vs)
125     {
126         ALOGV("setVideoSource(%d)", vs);
127         Parcel data, reply;
128         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
129         data.writeInt32(vs);
130         remote()->transact(SET_VIDEO_SOURCE, data, &reply);
131         return reply.readInt32();
132     }
133 
setAudioSource(int as)134     status_t setAudioSource(int as)
135     {
136         ALOGV("setAudioSource(%d)", as);
137         Parcel data, reply;
138         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
139         data.writeInt32(as);
140         remote()->transact(SET_AUDIO_SOURCE, data, &reply);
141         return reply.readInt32();
142     }
143 
setOutputFormat(int of)144     status_t setOutputFormat(int of)
145     {
146         ALOGV("setOutputFormat(%d)", of);
147         Parcel data, reply;
148         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
149         data.writeInt32(of);
150         remote()->transact(SET_OUTPUT_FORMAT, data, &reply);
151         return reply.readInt32();
152     }
153 
setVideoEncoder(int ve)154     status_t setVideoEncoder(int ve)
155     {
156         ALOGV("setVideoEncoder(%d)", ve);
157         Parcel data, reply;
158         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
159         data.writeInt32(ve);
160         remote()->transact(SET_VIDEO_ENCODER, data, &reply);
161         return reply.readInt32();
162     }
163 
setAudioEncoder(int ae)164     status_t setAudioEncoder(int ae)
165     {
166         ALOGV("setAudioEncoder(%d)", ae);
167         Parcel data, reply;
168         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
169         data.writeInt32(ae);
170         remote()->transact(SET_AUDIO_ENCODER, data, &reply);
171         return reply.readInt32();
172     }
173 
setOutputFile(int fd,int64_t offset,int64_t length)174     status_t setOutputFile(int fd, int64_t offset, int64_t length) {
175         ALOGV("setOutputFile(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length);
176         Parcel data, reply;
177         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
178         data.writeFileDescriptor(fd);
179         data.writeInt64(offset);
180         data.writeInt64(length);
181         remote()->transact(SET_OUTPUT_FILE_FD, data, &reply);
182         return reply.readInt32();
183     }
184 
setVideoSize(int width,int height)185     status_t setVideoSize(int width, int height)
186     {
187         ALOGV("setVideoSize(%dx%d)", width, height);
188         Parcel data, reply;
189         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
190         data.writeInt32(width);
191         data.writeInt32(height);
192         remote()->transact(SET_VIDEO_SIZE, data, &reply);
193         return reply.readInt32();
194     }
195 
setVideoFrameRate(int frames_per_second)196     status_t setVideoFrameRate(int frames_per_second)
197     {
198         ALOGV("setVideoFrameRate(%d)", frames_per_second);
199         Parcel data, reply;
200         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
201         data.writeInt32(frames_per_second);
202         remote()->transact(SET_VIDEO_FRAMERATE, data, &reply);
203         return reply.readInt32();
204     }
205 
setParameters(const String8 & params)206     status_t setParameters(const String8& params)
207     {
208         ALOGV("setParameter(%s)", params.string());
209         Parcel data, reply;
210         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
211         data.writeString8(params);
212         remote()->transact(SET_PARAMETERS, data, &reply);
213         return reply.readInt32();
214     }
215 
setListener(const sp<IMediaRecorderClient> & listener)216     status_t setListener(const sp<IMediaRecorderClient>& listener)
217     {
218         ALOGV("setListener(%p)", listener.get());
219         Parcel data, reply;
220         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
221         data.writeStrongBinder(IInterface::asBinder(listener));
222         remote()->transact(SET_LISTENER, data, &reply);
223         return reply.readInt32();
224     }
225 
setClientName(const String16 & clientName)226     status_t setClientName(const String16& clientName)
227     {
228         ALOGV("setClientName(%s)", String8(clientName).string());
229         Parcel data, reply;
230         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
231         data.writeString16(clientName);
232         remote()->transact(SET_CLIENT_NAME, data, &reply);
233         return reply.readInt32();
234     }
235 
prepare()236     status_t prepare()
237     {
238         ALOGV("prepare");
239         Parcel data, reply;
240         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
241         remote()->transact(PREPARE, data, &reply);
242         return reply.readInt32();
243     }
244 
getMaxAmplitude(int * max)245     status_t getMaxAmplitude(int* max)
246     {
247         ALOGV("getMaxAmplitude");
248         Parcel data, reply;
249         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
250         remote()->transact(GET_MAX_AMPLITUDE, data, &reply);
251         *max = reply.readInt32();
252         return reply.readInt32();
253     }
254 
start()255     status_t start()
256     {
257         ALOGV("start");
258         Parcel data, reply;
259         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
260         remote()->transact(START, data, &reply);
261         return reply.readInt32();
262     }
263 
stop()264     status_t stop()
265     {
266         ALOGV("stop");
267         Parcel data, reply;
268         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
269         remote()->transact(STOP, data, &reply);
270         return reply.readInt32();
271     }
272 
reset()273     status_t reset()
274     {
275         ALOGV("reset");
276         Parcel data, reply;
277         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
278         remote()->transact(RESET, data, &reply);
279         return reply.readInt32();
280     }
281 
pause()282     status_t pause()
283     {
284         ALOGV("pause");
285         Parcel data, reply;
286         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
287         remote()->transact(PAUSE, data, &reply);
288         return reply.readInt32();
289     }
290 
resume()291     status_t resume()
292     {
293         ALOGV("resume");
294         Parcel data, reply;
295         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
296         remote()->transact(RESUME, data, &reply);
297         return reply.readInt32();
298     }
299 
close()300     status_t close()
301     {
302         ALOGV("close");
303         Parcel data, reply;
304         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
305         remote()->transact(CLOSE, data, &reply);
306         return reply.readInt32();
307     }
308 
release()309     status_t release()
310     {
311         ALOGV("release");
312         Parcel data, reply;
313         data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
314         remote()->transact(RELEASE, data, &reply);
315         return reply.readInt32();
316     }
317 };
318 
319 IMPLEMENT_META_INTERFACE(MediaRecorder, "android.media.IMediaRecorder");
320 
321 // ----------------------------------------------------------------------
322 
onTransact(uint32_t code,const Parcel & data,Parcel * reply,uint32_t flags)323 status_t BnMediaRecorder::onTransact(
324                                      uint32_t code, const Parcel& data, Parcel* reply,
325                                      uint32_t flags)
326 {
327     switch (code) {
328         case RELEASE: {
329             ALOGV("RELEASE");
330             CHECK_INTERFACE(IMediaRecorder, data, reply);
331             reply->writeInt32(release());
332             return NO_ERROR;
333         } break;
334         case INIT: {
335             ALOGV("INIT");
336             CHECK_INTERFACE(IMediaRecorder, data, reply);
337             reply->writeInt32(init());
338             return NO_ERROR;
339         } break;
340         case CLOSE: {
341             ALOGV("CLOSE");
342             CHECK_INTERFACE(IMediaRecorder, data, reply);
343             reply->writeInt32(close());
344             return NO_ERROR;
345         } break;
346         case RESET: {
347             ALOGV("RESET");
348             CHECK_INTERFACE(IMediaRecorder, data, reply);
349             reply->writeInt32(reset());
350             return NO_ERROR;
351         } break;
352         case STOP: {
353             ALOGV("STOP");
354             CHECK_INTERFACE(IMediaRecorder, data, reply);
355             reply->writeInt32(stop());
356             return NO_ERROR;
357         } break;
358         case START: {
359             ALOGV("START");
360             CHECK_INTERFACE(IMediaRecorder, data, reply);
361             reply->writeInt32(start());
362             return NO_ERROR;
363         } break;
364         case PAUSE: {
365             ALOGV("PAUSE");
366             CHECK_INTERFACE(IMediaRecorder, data, reply);
367             reply->writeInt32(pause());
368             return NO_ERROR;
369         } break;
370         case RESUME: {
371             ALOGV("RESUME");
372             CHECK_INTERFACE(IMediaRecorder, data, reply);
373             reply->writeInt32(resume());
374             return NO_ERROR;
375         } break;
376         case PREPARE: {
377             ALOGV("PREPARE");
378             CHECK_INTERFACE(IMediaRecorder, data, reply);
379             reply->writeInt32(prepare());
380             return NO_ERROR;
381         } break;
382         case GET_MAX_AMPLITUDE: {
383             ALOGV("GET_MAX_AMPLITUDE");
384             CHECK_INTERFACE(IMediaRecorder, data, reply);
385             int max = 0;
386             status_t ret = getMaxAmplitude(&max);
387             reply->writeInt32(max);
388             reply->writeInt32(ret);
389             return NO_ERROR;
390         } break;
391         case SET_VIDEO_SOURCE: {
392             ALOGV("SET_VIDEO_SOURCE");
393             CHECK_INTERFACE(IMediaRecorder, data, reply);
394             int vs = data.readInt32();
395             reply->writeInt32(setVideoSource(vs));
396             return NO_ERROR;
397         } break;
398         case SET_AUDIO_SOURCE: {
399             ALOGV("SET_AUDIO_SOURCE");
400             CHECK_INTERFACE(IMediaRecorder, data, reply);
401             int as = data.readInt32();
402             reply->writeInt32(setAudioSource(as));
403             return NO_ERROR;
404         } break;
405         case SET_OUTPUT_FORMAT: {
406             ALOGV("SET_OUTPUT_FORMAT");
407             CHECK_INTERFACE(IMediaRecorder, data, reply);
408             int of = data.readInt32();
409             reply->writeInt32(setOutputFormat(of));
410             return NO_ERROR;
411         } break;
412         case SET_VIDEO_ENCODER: {
413             ALOGV("SET_VIDEO_ENCODER");
414             CHECK_INTERFACE(IMediaRecorder, data, reply);
415             int ve = data.readInt32();
416             reply->writeInt32(setVideoEncoder(ve));
417             return NO_ERROR;
418         } break;
419         case SET_AUDIO_ENCODER: {
420             ALOGV("SET_AUDIO_ENCODER");
421             CHECK_INTERFACE(IMediaRecorder, data, reply);
422             int ae = data.readInt32();
423             reply->writeInt32(setAudioEncoder(ae));
424             return NO_ERROR;
425 
426         } break;
427         case SET_OUTPUT_FILE_FD: {
428             ALOGV("SET_OUTPUT_FILE_FD");
429             CHECK_INTERFACE(IMediaRecorder, data, reply);
430             int fd = dup(data.readFileDescriptor());
431             int64_t offset = data.readInt64();
432             int64_t length = data.readInt64();
433             reply->writeInt32(setOutputFile(fd, offset, length));
434             ::close(fd);
435             return NO_ERROR;
436         } break;
437         case SET_VIDEO_SIZE: {
438             ALOGV("SET_VIDEO_SIZE");
439             CHECK_INTERFACE(IMediaRecorder, data, reply);
440             int width = data.readInt32();
441             int height = data.readInt32();
442             reply->writeInt32(setVideoSize(width, height));
443             return NO_ERROR;
444         } break;
445         case SET_VIDEO_FRAMERATE: {
446             ALOGV("SET_VIDEO_FRAMERATE");
447             CHECK_INTERFACE(IMediaRecorder, data, reply);
448             int frames_per_second = data.readInt32();
449             reply->writeInt32(setVideoFrameRate(frames_per_second));
450             return NO_ERROR;
451         } break;
452         case SET_PARAMETERS: {
453             ALOGV("SET_PARAMETER");
454             CHECK_INTERFACE(IMediaRecorder, data, reply);
455             reply->writeInt32(setParameters(data.readString8()));
456             return NO_ERROR;
457         } break;
458         case SET_LISTENER: {
459             ALOGV("SET_LISTENER");
460             CHECK_INTERFACE(IMediaRecorder, data, reply);
461             sp<IMediaRecorderClient> listener =
462                 interface_cast<IMediaRecorderClient>(data.readStrongBinder());
463             reply->writeInt32(setListener(listener));
464             return NO_ERROR;
465         } break;
466         case SET_CLIENT_NAME: {
467             ALOGV("SET_CLIENT_NAME");
468             CHECK_INTERFACE(IMediaRecorder, data, reply);
469             reply->writeInt32(setClientName(data.readString16()));
470             return NO_ERROR;
471         }
472         case SET_PREVIEW_SURFACE: {
473             ALOGV("SET_PREVIEW_SURFACE");
474             CHECK_INTERFACE(IMediaRecorder, data, reply);
475             sp<IGraphicBufferProducer> surface = interface_cast<IGraphicBufferProducer>(
476                     data.readStrongBinder());
477             reply->writeInt32(setPreviewSurface(surface));
478             return NO_ERROR;
479         } break;
480         case SET_CAMERA: {
481             ALOGV("SET_CAMERA");
482             CHECK_INTERFACE(IMediaRecorder, data, reply);
483             sp<hardware::ICamera> camera =
484                     interface_cast<hardware::ICamera>(data.readStrongBinder());
485             sp<ICameraRecordingProxy> proxy =
486                     interface_cast<ICameraRecordingProxy>(data.readStrongBinder());
487             reply->writeInt32(setCamera(camera, proxy));
488             return NO_ERROR;
489         } break;
490         case SET_INPUT_SURFACE: {
491             ALOGV("SET_INPUT_SURFACE");
492             CHECK_INTERFACE(IMediaRecorder, data, reply);
493             sp<IGraphicBufferConsumer> surface = interface_cast<IGraphicBufferConsumer>(
494                     data.readStrongBinder());
495             reply->writeInt32(setInputSurface(surface));
496             return NO_ERROR;
497         } break;
498         case QUERY_SURFACE_MEDIASOURCE: {
499             ALOGV("QUERY_SURFACE_MEDIASOURCE");
500             CHECK_INTERFACE(IMediaRecorder, data, reply);
501             // call the mediaserver side to create
502             // a surfacemediasource
503             sp<IGraphicBufferProducer> surfaceMediaSource = querySurfaceMediaSource();
504             // The mediaserver might have failed to create a source
505             int returnedNull= (surfaceMediaSource == NULL) ? 1 : 0 ;
506             reply->writeInt32(returnedNull);
507             if (!returnedNull) {
508                 reply->writeStrongBinder(IInterface::asBinder(surfaceMediaSource));
509             }
510             return NO_ERROR;
511         } break;
512         default:
513             return BBinder::onTransact(code, data, reply, flags);
514     }
515 }
516 
517 // ----------------------------------------------------------------------------
518 
519 } // namespace android
520