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<IGraphicBufferConsumer>& 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, int64_t offset, int64_t length)
165{
166    ALOGV("setOutputFile(%d, %lld, %lld)", fd, (long long)offset, (long long)length);
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, offset, length);
173}
174
175status_t MediaRecorderClient::setVideoSize(int width, int height)
176{
177    ALOGV("setVideoSize(%dx%d)", width, height);
178    Mutex::Autolock lock(mLock);
179    if (mRecorder == NULL) {
180        ALOGE("recorder is not initialized");
181        return NO_INIT;
182    }
183    return mRecorder->setVideoSize(width, height);
184}
185
186status_t MediaRecorderClient::setVideoFrameRate(int frames_per_second)
187{
188    ALOGV("setVideoFrameRate(%d)", frames_per_second);
189    Mutex::Autolock lock(mLock);
190    if (mRecorder == NULL) {
191        ALOGE("recorder is not initialized");
192        return NO_INIT;
193    }
194    return mRecorder->setVideoFrameRate(frames_per_second);
195}
196
197status_t MediaRecorderClient::setParameters(const String8& params) {
198    ALOGV("setParameters(%s)", params.string());
199    Mutex::Autolock lock(mLock);
200    if (mRecorder == NULL) {
201        ALOGE("recorder is not initialized");
202        return NO_INIT;
203    }
204    return mRecorder->setParameters(params);
205}
206
207status_t MediaRecorderClient::prepare()
208{
209    ALOGV("prepare");
210    Mutex::Autolock lock(mLock);
211    if (mRecorder == NULL) {
212        ALOGE("recorder is not initialized");
213        return NO_INIT;
214    }
215    return mRecorder->prepare();
216}
217
218
219status_t MediaRecorderClient::getMaxAmplitude(int* max)
220{
221    ALOGV("getMaxAmplitude");
222    Mutex::Autolock lock(mLock);
223    if (mRecorder == NULL) {
224        ALOGE("recorder is not initialized");
225        return NO_INIT;
226    }
227    return mRecorder->getMaxAmplitude(max);
228}
229
230status_t MediaRecorderClient::start()
231{
232    ALOGV("start");
233    Mutex::Autolock lock(mLock);
234    if (mRecorder == NULL) {
235        ALOGE("recorder is not initialized");
236        return NO_INIT;
237    }
238    return mRecorder->start();
239
240}
241
242status_t MediaRecorderClient::stop()
243{
244    ALOGV("stop");
245    Mutex::Autolock lock(mLock);
246    if (mRecorder == NULL) {
247        ALOGE("recorder is not initialized");
248        return NO_INIT;
249    }
250    return mRecorder->stop();
251}
252
253status_t MediaRecorderClient::pause()
254{
255    ALOGV("pause");
256    Mutex::Autolock lock(mLock);
257    if (mRecorder == NULL) {
258        ALOGE("recorder is not initialized");
259        return NO_INIT;
260    }
261    return mRecorder->pause();
262
263}
264
265status_t MediaRecorderClient::resume()
266{
267    ALOGV("resume");
268    Mutex::Autolock lock(mLock);
269    if (mRecorder == NULL) {
270        ALOGE("recorder is not initialized");
271        return NO_INIT;
272    }
273    return mRecorder->resume();
274}
275
276status_t MediaRecorderClient::init()
277{
278    ALOGV("init");
279    Mutex::Autolock lock(mLock);
280    if (mRecorder == NULL) {
281        ALOGE("recorder is not initialized");
282        return NO_INIT;
283    }
284    return mRecorder->init();
285}
286
287status_t MediaRecorderClient::close()
288{
289    ALOGV("close");
290    Mutex::Autolock lock(mLock);
291    if (mRecorder == NULL) {
292        ALOGE("recorder is not initialized");
293        return NO_INIT;
294    }
295    return mRecorder->close();
296}
297
298
299status_t MediaRecorderClient::reset()
300{
301    ALOGV("reset");
302    Mutex::Autolock lock(mLock);
303    if (mRecorder == NULL) {
304        ALOGE("recorder is not initialized");
305        return NO_INIT;
306    }
307    return mRecorder->reset();
308}
309
310status_t MediaRecorderClient::release()
311{
312    ALOGV("release");
313    Mutex::Autolock lock(mLock);
314    if (mRecorder != NULL) {
315        delete mRecorder;
316        mRecorder = NULL;
317        wp<MediaRecorderClient> client(this);
318        mMediaPlayerService->removeMediaRecorderClient(client);
319    }
320    return NO_ERROR;
321}
322
323MediaRecorderClient::MediaRecorderClient(const sp<MediaPlayerService>& service, pid_t pid,
324        const String16& opPackageName)
325{
326    ALOGV("Client constructor");
327    mPid = pid;
328    mRecorder = new StagefrightRecorder(opPackageName);
329    mMediaPlayerService = service;
330}
331
332MediaRecorderClient::~MediaRecorderClient()
333{
334    ALOGV("Client destructor");
335    release();
336}
337
338MediaRecorderClient::ServiceDeathNotifier::ServiceDeathNotifier(
339        const sp<IBinder>& service,
340        const sp<IMediaRecorderClient>& listener,
341        int which) {
342    mService = service;
343    mListener = listener;
344    mWhich = which;
345}
346
347MediaRecorderClient::ServiceDeathNotifier::~ServiceDeathNotifier() {
348    mService->unlinkToDeath(this);
349}
350
351void  MediaRecorderClient::ServiceDeathNotifier::binderDied(const wp<IBinder>& /*who*/) {
352    sp<IMediaRecorderClient> listener = mListener.promote();
353    if (listener != NULL) {
354        listener->notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
355    } else {
356        ALOGW("listener for process %d death is gone", mWhich);
357    }
358}
359
360status_t MediaRecorderClient::setListener(const sp<IMediaRecorderClient>& listener)
361{
362    ALOGV("setListener");
363    Mutex::Autolock lock(mLock);
364    if (mRecorder == NULL) {
365        ALOGE("recorder is not initialized");
366        return NO_INIT;
367    }
368    mRecorder->setListener(listener);
369
370    sp<IServiceManager> sm = defaultServiceManager();
371    sp<IBinder> binder = sm->getService(String16("media.camera"));
372    mCameraDeathListener = new ServiceDeathNotifier(binder, listener,
373            MediaPlayerService::CAMERA_PROCESS_DEATH);
374    binder->linkToDeath(mCameraDeathListener);
375
376    binder = sm->getService(String16("media.codec"));
377    mCodecDeathListener = new ServiceDeathNotifier(binder, listener,
378            MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
379    binder->linkToDeath(mCodecDeathListener);
380
381    return OK;
382}
383
384status_t MediaRecorderClient::setClientName(const String16& clientName) {
385    ALOGV("setClientName(%s)", String8(clientName).string());
386    Mutex::Autolock lock(mLock);
387    if (mRecorder == NULL) {
388        ALOGE("recorder is not initialized");
389        return NO_INIT;
390    }
391    return mRecorder->setClientName(clientName);
392}
393
394status_t MediaRecorderClient::dump(int fd, const Vector<String16>& args) {
395    if (mRecorder != NULL) {
396        return mRecorder->dump(fd, args);
397    }
398    return OK;
399}
400
401}; // namespace android
402