MediaRecorderClient.cpp revision 9c47c97ecac581d66b6febafd156618247e86742
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    clearDeathNotifiers();
332    return NO_ERROR;
333}
334
335MediaRecorderClient::MediaRecorderClient(const sp<MediaPlayerService>& service, pid_t pid,
336        const String16& opPackageName)
337{
338    ALOGV("Client constructor");
339    mPid = pid;
340    mRecorder = new StagefrightRecorder(opPackageName);
341    mMediaPlayerService = service;
342}
343
344MediaRecorderClient::~MediaRecorderClient()
345{
346    ALOGV("Client destructor");
347    release();
348}
349
350MediaRecorderClient::ServiceDeathNotifier::ServiceDeathNotifier(
351        const sp<IBinder>& service,
352        const sp<IMediaRecorderClient>& listener,
353        int which) {
354    mService = service;
355    mOmx = nullptr;
356    mListener = listener;
357    mWhich = which;
358}
359
360MediaRecorderClient::ServiceDeathNotifier::ServiceDeathNotifier(
361        const sp<IOmx>& omx,
362        const sp<IMediaRecorderClient>& listener,
363        int which) {
364    mService = nullptr;
365    mOmx = omx;
366    mListener = listener;
367    mWhich = which;
368}
369
370MediaRecorderClient::ServiceDeathNotifier::~ServiceDeathNotifier() {
371}
372
373void MediaRecorderClient::ServiceDeathNotifier::binderDied(const wp<IBinder>& /*who*/) {
374    sp<IMediaRecorderClient> listener = mListener.promote();
375    if (listener != NULL) {
376        listener->notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
377    } else {
378        ALOGW("listener for process %d death is gone", mWhich);
379    }
380}
381
382void MediaRecorderClient::ServiceDeathNotifier::serviceDied(
383        uint64_t /* cookie */,
384        const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
385    sp<IMediaRecorderClient> listener = mListener.promote();
386    if (listener != NULL) {
387        listener->notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
388    } else {
389        ALOGW("listener for process %d death is gone", mWhich);
390    }
391}
392
393void MediaRecorderClient::ServiceDeathNotifier::unlinkToDeath() {
394    if (mService != nullptr) {
395        mService->unlinkToDeath(this);
396        mService = nullptr;
397    } else if (mOmx != nullptr) {
398        mOmx->unlinkToDeath(this);
399        mOmx = nullptr;
400    }
401}
402
403void MediaRecorderClient::clearDeathNotifiers() {
404    if (mCameraDeathListener != nullptr) {
405        mCameraDeathListener->unlinkToDeath();
406        mCameraDeathListener = nullptr;
407    }
408    if (mCodecDeathListener != nullptr) {
409        mCodecDeathListener->unlinkToDeath();
410        mCodecDeathListener = nullptr;
411    }
412}
413
414status_t MediaRecorderClient::setListener(const sp<IMediaRecorderClient>& listener)
415{
416    ALOGV("setListener");
417    clearDeathNotifiers();
418    Mutex::Autolock lock(mLock);
419    if (mRecorder == NULL) {
420        ALOGE("recorder is not initialized");
421        return NO_INIT;
422    }
423    mRecorder->setListener(listener);
424
425    sp<IServiceManager> sm = defaultServiceManager();
426
427    // WORKAROUND: We don't know if camera exists here and getService might block for 5 seconds.
428    // Use checkService for camera if we don't know it exists.
429    static std::atomic<bool> sCameraChecked(false);  // once true never becomes false.
430    static std::atomic<bool> sCameraVerified(false); // once true never becomes false.
431    sp<IBinder> binder = (sCameraVerified || !sCameraChecked)
432        ? sm->getService(String16("media.camera")) : sm->checkService(String16("media.camera"));
433    // If the device does not have a camera, do not create a death listener for it.
434    if (binder != NULL) {
435        sCameraVerified = true;
436        mCameraDeathListener = new ServiceDeathNotifier(binder, listener,
437                MediaPlayerService::CAMERA_PROCESS_DEATH);
438        binder->linkToDeath(mCameraDeathListener);
439    }
440    sCameraChecked = true;
441
442    int32_t trebleOmx = property_get_int32("persist.media.treble_omx", -1);
443    if ((trebleOmx == 1) || ((trebleOmx == -1) &&
444            property_get_bool("persist.hal.binderization", 0))) {
445        // Treble IOmx
446        sp<IOmx> omx = IOmx::getService();
447        if (omx == nullptr) {
448            ALOGE("Treble IOmx not available");
449            return NO_INIT;
450        }
451        mCodecDeathListener = new ServiceDeathNotifier(omx, listener,
452                MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
453        omx->linkToDeath(mCodecDeathListener, 0);
454    } else {
455        // Legacy IOMX
456        binder = sm->getService(String16("media.codec"));
457        mCodecDeathListener = new ServiceDeathNotifier(binder, listener,
458                MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
459        binder->linkToDeath(mCodecDeathListener);
460    }
461
462    return OK;
463}
464
465status_t MediaRecorderClient::setClientName(const String16& clientName) {
466    ALOGV("setClientName(%s)", String8(clientName).string());
467    Mutex::Autolock lock(mLock);
468    if (mRecorder == NULL) {
469        ALOGE("recorder is not initialized");
470        return NO_INIT;
471    }
472    return mRecorder->setClientName(clientName);
473}
474
475status_t MediaRecorderClient::dump(int fd, const Vector<String16>& args) {
476    if (mRecorder != NULL) {
477        return mRecorder->dump(fd, args);
478    }
479    return OK;
480}
481
482}; // namespace android
483