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
32namespace android {
33
34enum {
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
60class BpMediaRecorder: public BpInterface<IMediaRecorder>
61{
62public:
63    BpMediaRecorder(const sp<IBinder>& impl)
64    : BpInterface<IMediaRecorder>(impl)
65    {
66    }
67
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
298IMPLEMENT_META_INTERFACE(MediaRecorder, "android.media.IMediaRecorder");
299
300// ----------------------------------------------------------------------
301
302status_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