MediaRecorderClient.cpp revision fe44e4f74fe2582cbf012687059278dbcbdaa6f7
1/*
2 ** Copyright 2008, The Android Open Source Project
3 **
4 ** Licensed under the Apache License, Version 2.0 (the "License");
5 ** you may not use this file except in compliance with the License.
6 ** You may obtain a copy of the License at
7 **
8 **     http://www.apache.org/licenses/LICENSE-2.0
9 **
10 ** Unless required by applicable law or agreed to in writing, software
11 ** distributed under the License is distributed on an "AS IS" BASIS,
12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 ** See the License for the specific language governing permissions and
14 ** limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "MediaRecorderService"
19#include <utils/Log.h>
20
21#include <sys/types.h>
22#include <sys/stat.h>
23#include <dirent.h>
24#include <unistd.h>
25#include <string.h>
26#include <cutils/atomic.h>
27#include <cutils/properties.h> // for property_get
28#include <binder/IPCThreadState.h>
29#include <binder/IServiceManager.h>
30#include <binder/MemoryHeapBase.h>
31#include <binder/MemoryBase.h>
32
33#include <utils/String16.h>
34
35#include <system/audio.h>
36
37#include "MediaRecorderClient.h"
38#include "MediaPlayerService.h"
39
40#include "StagefrightRecorder.h"
41#include <gui/IGraphicBufferProducer.h>
42
43namespace android {
44
45const char* cameraPermission = "android.permission.CAMERA";
46const char* recordAudioPermission = "android.permission.RECORD_AUDIO";
47
48static bool checkPermission(const char* permissionString) {
49    if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
50    bool ok = checkCallingPermission(String16(permissionString));
51    if (!ok) ALOGE("Request requires %s", permissionString);
52    return ok;
53}
54
55status_t MediaRecorderClient::setInputSurface(const sp<PersistentSurface>& surface)
56{
57    ALOGV("setInputSurface");
58    Mutex::Autolock lock(mLock);
59    if (mRecorder == NULL) {
60        ALOGE("recorder is not initialized");
61        return NO_INIT;
62    }
63    return mRecorder->setInputSurface(surface);
64}
65
66sp<IGraphicBufferProducer> MediaRecorderClient::querySurfaceMediaSource()
67{
68    ALOGV("Query SurfaceMediaSource");
69    Mutex::Autolock lock(mLock);
70    if (mRecorder == NULL) {
71        ALOGE("recorder is not initialized");
72        return NULL;
73    }
74    return mRecorder->querySurfaceMediaSource();
75}
76
77
78
79status_t MediaRecorderClient::setCamera(const sp<hardware::ICamera>& camera,
80                                        const sp<ICameraRecordingProxy>& proxy)
81{
82    ALOGV("setCamera");
83    Mutex::Autolock lock(mLock);
84    if (mRecorder == NULL) {
85        ALOGE("recorder is not initialized");
86        return NO_INIT;
87    }
88    return mRecorder->setCamera(camera, proxy);
89}
90
91status_t MediaRecorderClient::setPreviewSurface(const sp<IGraphicBufferProducer>& surface)
92{
93    ALOGV("setPreviewSurface");
94    Mutex::Autolock lock(mLock);
95    if (mRecorder == NULL) {
96        ALOGE("recorder is not initialized");
97        return NO_INIT;
98    }
99    return mRecorder->setPreviewSurface(surface);
100}
101
102status_t MediaRecorderClient::setVideoSource(int vs)
103{
104    ALOGV("setVideoSource(%d)", vs);
105    // Check camera permission for sources other than SURFACE
106    if (vs != VIDEO_SOURCE_SURFACE && !checkPermission(cameraPermission)) {
107        return PERMISSION_DENIED;
108    }
109    Mutex::Autolock lock(mLock);
110    if (mRecorder == NULL)     {
111        ALOGE("recorder is not initialized");
112        return NO_INIT;
113    }
114    return mRecorder->setVideoSource((video_source)vs);
115}
116
117status_t MediaRecorderClient::setAudioSource(int as)
118{
119    ALOGV("setAudioSource(%d)", as);
120    if (!checkPermission(recordAudioPermission)) {
121        return PERMISSION_DENIED;
122    }
123    Mutex::Autolock lock(mLock);
124    if (mRecorder == NULL)  {
125        ALOGE("recorder is not initialized");
126        return NO_INIT;
127    }
128    return mRecorder->setAudioSource((audio_source_t)as);
129}
130
131status_t MediaRecorderClient::setOutputFormat(int of)
132{
133    ALOGV("setOutputFormat(%d)", of);
134    Mutex::Autolock lock(mLock);
135    if (mRecorder == NULL) {
136        ALOGE("recorder is not initialized");
137        return NO_INIT;
138    }
139    return mRecorder->setOutputFormat((output_format)of);
140}
141
142status_t MediaRecorderClient::setVideoEncoder(int ve)
143{
144    ALOGV("setVideoEncoder(%d)", ve);
145    Mutex::Autolock lock(mLock);
146    if (mRecorder == NULL) {
147        ALOGE("recorder is not initialized");
148        return NO_INIT;
149    }
150    return mRecorder->setVideoEncoder((video_encoder)ve);
151}
152
153status_t MediaRecorderClient::setAudioEncoder(int ae)
154{
155    ALOGV("setAudioEncoder(%d)", ae);
156    Mutex::Autolock lock(mLock);
157    if (mRecorder == NULL) {
158        ALOGE("recorder is not initialized");
159        return NO_INIT;
160    }
161    return mRecorder->setAudioEncoder((audio_encoder)ae);
162}
163
164status_t MediaRecorderClient::setOutputFile(int fd)
165{
166    ALOGV("setOutputFile(%d)", fd);
167    Mutex::Autolock lock(mLock);
168    if (mRecorder == NULL) {
169        ALOGE("recorder is not initialized");
170        return NO_INIT;
171    }
172    return mRecorder->setOutputFile(fd);
173}
174
175status_t MediaRecorderClient::setNextOutputFile(int fd)
176{
177    ALOGV("setNextOutputFile(%d)", fd);
178    Mutex::Autolock lock(mLock);
179    if (mRecorder == NULL) {
180        ALOGE("recorder is not initialized");
181        return NO_INIT;
182    }
183    return mRecorder->setNextOutputFile(fd);
184}
185
186status_t MediaRecorderClient::setVideoSize(int width, int height)
187{
188    ALOGV("setVideoSize(%dx%d)", width, height);
189    Mutex::Autolock lock(mLock);
190    if (mRecorder == NULL) {
191        ALOGE("recorder is not initialized");
192        return NO_INIT;
193    }
194    return mRecorder->setVideoSize(width, height);
195}
196
197status_t MediaRecorderClient::setVideoFrameRate(int frames_per_second)
198{
199    ALOGV("setVideoFrameRate(%d)", frames_per_second);
200    Mutex::Autolock lock(mLock);
201    if (mRecorder == NULL) {
202        ALOGE("recorder is not initialized");
203        return NO_INIT;
204    }
205    return mRecorder->setVideoFrameRate(frames_per_second);
206}
207
208status_t MediaRecorderClient::setParameters(const String8& params) {
209    ALOGV("setParameters(%s)", params.string());
210    Mutex::Autolock lock(mLock);
211    if (mRecorder == NULL) {
212        ALOGE("recorder is not initialized");
213        return NO_INIT;
214    }
215    return mRecorder->setParameters(params);
216}
217
218status_t MediaRecorderClient::prepare()
219{
220    ALOGV("prepare");
221    Mutex::Autolock lock(mLock);
222    if (mRecorder == NULL) {
223        ALOGE("recorder is not initialized");
224        return NO_INIT;
225    }
226    return mRecorder->prepare();
227}
228
229
230status_t MediaRecorderClient::getMaxAmplitude(int* max)
231{
232    ALOGV("getMaxAmplitude");
233    Mutex::Autolock lock(mLock);
234    if (mRecorder == NULL) {
235        ALOGE("recorder is not initialized");
236        return NO_INIT;
237    }
238    return mRecorder->getMaxAmplitude(max);
239}
240
241status_t MediaRecorderClient::start()
242{
243    ALOGV("start");
244    Mutex::Autolock lock(mLock);
245    if (mRecorder == NULL) {
246        ALOGE("recorder is not initialized");
247        return NO_INIT;
248    }
249    return mRecorder->start();
250
251}
252
253status_t MediaRecorderClient::stop()
254{
255    ALOGV("stop");
256    Mutex::Autolock lock(mLock);
257    if (mRecorder == NULL) {
258        ALOGE("recorder is not initialized");
259        return NO_INIT;
260    }
261    return mRecorder->stop();
262}
263
264status_t MediaRecorderClient::pause()
265{
266    ALOGV("pause");
267    Mutex::Autolock lock(mLock);
268    if (mRecorder == NULL) {
269        ALOGE("recorder is not initialized");
270        return NO_INIT;
271    }
272    return mRecorder->pause();
273
274}
275
276status_t MediaRecorderClient::resume()
277{
278    ALOGV("resume");
279    Mutex::Autolock lock(mLock);
280    if (mRecorder == NULL) {
281        ALOGE("recorder is not initialized");
282        return NO_INIT;
283    }
284    return mRecorder->resume();
285}
286
287status_t MediaRecorderClient::init()
288{
289    ALOGV("init");
290    Mutex::Autolock lock(mLock);
291    if (mRecorder == NULL) {
292        ALOGE("recorder is not initialized");
293        return NO_INIT;
294    }
295    return mRecorder->init();
296}
297
298status_t MediaRecorderClient::close()
299{
300    ALOGV("close");
301    Mutex::Autolock lock(mLock);
302    if (mRecorder == NULL) {
303        ALOGE("recorder is not initialized");
304        return NO_INIT;
305    }
306    return mRecorder->close();
307}
308
309
310status_t MediaRecorderClient::reset()
311{
312    ALOGV("reset");
313    Mutex::Autolock lock(mLock);
314    if (mRecorder == NULL) {
315        ALOGE("recorder is not initialized");
316        return NO_INIT;
317    }
318    return mRecorder->reset();
319}
320
321status_t MediaRecorderClient::release()
322{
323    ALOGV("release");
324    Mutex::Autolock lock(mLock);
325    if (mRecorder != NULL) {
326        delete mRecorder;
327        mRecorder = NULL;
328        wp<MediaRecorderClient> client(this);
329        mMediaPlayerService->removeMediaRecorderClient(client);
330    }
331    return NO_ERROR;
332}
333
334MediaRecorderClient::MediaRecorderClient(const sp<MediaPlayerService>& service, pid_t pid,
335        const String16& opPackageName)
336{
337    ALOGV("Client constructor");
338    mPid = pid;
339    mRecorder = new StagefrightRecorder(opPackageName);
340    mMediaPlayerService = service;
341}
342
343MediaRecorderClient::~MediaRecorderClient()
344{
345    ALOGV("Client destructor");
346    release();
347}
348
349MediaRecorderClient::ServiceDeathNotifier::ServiceDeathNotifier(
350        const sp<IBinder>& service,
351        const sp<IMediaRecorderClient>& listener,
352        int which) {
353    mService = service;
354    mListener = listener;
355    mWhich = which;
356}
357
358MediaRecorderClient::ServiceDeathNotifier::~ServiceDeathNotifier() {
359    mService->unlinkToDeath(this);
360}
361
362void  MediaRecorderClient::ServiceDeathNotifier::binderDied(const wp<IBinder>& /*who*/) {
363    sp<IMediaRecorderClient> listener = mListener.promote();
364    if (listener != NULL) {
365        listener->notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
366    } else {
367        ALOGW("listener for process %d death is gone", mWhich);
368    }
369}
370
371status_t MediaRecorderClient::setListener(const sp<IMediaRecorderClient>& listener)
372{
373    ALOGV("setListener");
374    Mutex::Autolock lock(mLock);
375    if (mRecorder == NULL) {
376        ALOGE("recorder is not initialized");
377        return NO_INIT;
378    }
379    mRecorder->setListener(listener);
380
381    sp<IServiceManager> sm = defaultServiceManager();
382
383    // WORKAROUND: We don't know if camera exists here and getService might block for 5 seconds.
384    // Use checkService for camera if we don't know it exists.
385    static std::atomic<bool> sCameraChecked(false);  // once true never becomes false.
386    static std::atomic<bool> sCameraVerified(false); // once true never becomes false.
387    sp<IBinder> binder = (sCameraVerified || !sCameraChecked)
388        ? sm->getService(String16("media.camera")) : sm->checkService(String16("media.camera"));
389    // If the device does not have a camera, do not create a death listener for it.
390    if (binder != NULL) {
391        sCameraVerified = true;
392        mCameraDeathListener = new ServiceDeathNotifier(binder, listener,
393                MediaPlayerService::CAMERA_PROCESS_DEATH);
394        binder->linkToDeath(mCameraDeathListener);
395    }
396    sCameraChecked = true;
397
398    binder = sm->getService(String16("media.codec"));
399    mCodecDeathListener = new ServiceDeathNotifier(binder, listener,
400            MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
401    binder->linkToDeath(mCodecDeathListener);
402
403    return OK;
404}
405
406status_t MediaRecorderClient::setClientName(const String16& clientName) {
407    ALOGV("setClientName(%s)", String8(clientName).string());
408    Mutex::Autolock lock(mLock);
409    if (mRecorder == NULL) {
410        ALOGE("recorder is not initialized");
411        return NO_INIT;
412    }
413    return mRecorder->setClientName(clientName);
414}
415
416status_t MediaRecorderClient::dump(int fd, const Vector<String16>& args) {
417    if (mRecorder != NULL) {
418        return mRecorder->dump(fd, args);
419    }
420    return OK;
421}
422
423}; // namespace android
424