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