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
33namespace android {
34
35enum {
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
63class BpMediaRecorder: public BpInterface<IMediaRecorder>
64{
65public:
66    BpMediaRecorder(const sp<IBinder>& impl)
67    : BpInterface<IMediaRecorder>(impl)
68    {
69    }
70
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
319IMPLEMENT_META_INTERFACE(MediaRecorder, "android.media.IMediaRecorder");
320
321// ----------------------------------------------------------------------
322
323status_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