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