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