CameraService.cpp revision f69c70ded4316ea3ee504ac779bd024433ed4ef7
1/*
2**
3** Copyright (C) 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_TAG "CameraService"
19//#define LOG_NDEBUG 0
20
21#include <stdio.h>
22#include <sys/types.h>
23#include <pthread.h>
24
25#include <binder/IPCThreadState.h>
26#include <binder/IServiceManager.h>
27#include <binder/MemoryBase.h>
28#include <binder/MemoryHeapBase.h>
29#include <cutils/atomic.h>
30#include <cutils/properties.h>
31#include <gui/SurfaceTextureClient.h>
32#include <gui/Surface.h>
33#include <hardware/hardware.h>
34#include <media/AudioSystem.h>
35#include <media/mediaplayer.h>
36#include <utils/Errors.h>
37#include <utils/Log.h>
38#include <utils/String16.h>
39
40#include "CameraService.h"
41#include "CameraClient.h"
42#include "Camera2Client.h"
43
44namespace android {
45
46// ----------------------------------------------------------------------------
47// Logging support -- this is for debugging only
48// Use "adb shell dumpsys media.camera -v 1" to change it.
49volatile int32_t gLogLevel = 0;
50
51#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
52#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
53
54static void setLogLevel(int level) {
55    android_atomic_write(level, &gLogLevel);
56}
57
58// ----------------------------------------------------------------------------
59
60static int getCallingPid() {
61    return IPCThreadState::self()->getCallingPid();
62}
63
64static int getCallingUid() {
65    return IPCThreadState::self()->getCallingUid();
66}
67
68// ----------------------------------------------------------------------------
69
70// This is ugly and only safe if we never re-create the CameraService, but
71// should be ok for now.
72static CameraService *gCameraService;
73
74CameraService::CameraService()
75:mSoundRef(0), mModule(0)
76{
77    ALOGI("CameraService started (pid=%d)", getpid());
78    gCameraService = this;
79}
80
81void CameraService::onFirstRef()
82{
83    BnCameraService::onFirstRef();
84
85    if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
86                (const hw_module_t **)&mModule) < 0) {
87        ALOGE("Could not load camera HAL module");
88        mNumberOfCameras = 0;
89    }
90    else {
91        mNumberOfCameras = mModule->get_number_of_cameras();
92        if (mNumberOfCameras > MAX_CAMERAS) {
93            ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
94                    mNumberOfCameras, MAX_CAMERAS);
95            mNumberOfCameras = MAX_CAMERAS;
96        }
97        for (int i = 0; i < mNumberOfCameras; i++) {
98            setCameraFree(i);
99        }
100    }
101}
102
103CameraService::~CameraService() {
104    for (int i = 0; i < mNumberOfCameras; i++) {
105        if (mBusy[i]) {
106            ALOGE("camera %d is still in use in destructor!", i);
107        }
108    }
109
110    gCameraService = NULL;
111}
112
113int32_t CameraService::getNumberOfCameras() {
114    return mNumberOfCameras;
115}
116
117status_t CameraService::getCameraInfo(int cameraId,
118                                      struct CameraInfo* cameraInfo) {
119    if (!mModule) {
120        return NO_INIT;
121    }
122
123    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
124        return BAD_VALUE;
125    }
126
127    struct camera_info info;
128    status_t rc = mModule->get_camera_info(cameraId, &info);
129    cameraInfo->facing = info.facing;
130    cameraInfo->orientation = info.orientation;
131    return rc;
132}
133
134sp<ICamera> CameraService::connect(
135        const sp<ICameraClient>& cameraClient, int cameraId) {
136    int callingPid = getCallingPid();
137
138    LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId);
139
140    if (!mModule) {
141        ALOGE("Camera HAL module not loaded");
142        return NULL;
143    }
144
145    sp<Client> client;
146    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
147        ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
148            callingPid, cameraId);
149        return NULL;
150    }
151
152    char value[PROPERTY_VALUE_MAX];
153    property_get("sys.secpolicy.camera.disabled", value, "0");
154    if (strcmp(value, "1") == 0) {
155        // Camera is disabled by DevicePolicyManager.
156        ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
157        return NULL;
158    }
159
160    Mutex::Autolock lock(mServiceLock);
161    if (mClient[cameraId] != 0) {
162        client = mClient[cameraId].promote();
163        if (client != 0) {
164            if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
165                LOG1("CameraService::connect X (pid %d) (the same client)",
166                     callingPid);
167                return client;
168            } else {
169                ALOGW("CameraService::connect X (pid %d) rejected (existing client).",
170                      callingPid);
171                return NULL;
172            }
173        }
174        mClient[cameraId].clear();
175    }
176
177    if (mBusy[cameraId]) {
178        ALOGW("CameraService::connect X (pid %d) rejected"
179                " (camera %d is still busy).", callingPid, cameraId);
180        return NULL;
181    }
182
183    struct camera_info info;
184    if (mModule->get_camera_info(cameraId, &info) != OK) {
185        ALOGE("Invalid camera id %d", cameraId);
186        return NULL;
187    }
188
189    int deviceVersion;
190    if (mModule->common.module_api_version == CAMERA_MODULE_API_VERSION_2_0) {
191        deviceVersion = info.device_version;
192    } else {
193        deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
194    }
195
196    switch(deviceVersion) {
197      case CAMERA_DEVICE_API_VERSION_1_0:
198        client = new CameraClient(this, cameraClient, cameraId,
199                info.facing, callingPid);
200        break;
201      case CAMERA_DEVICE_API_VERSION_2_0:
202        client = new Camera2Client(this, cameraClient, cameraId,
203                info.facing, callingPid);
204        break;
205      default:
206        ALOGE("Unknown camera device HAL version: %d", deviceVersion);
207        return NULL;
208    }
209
210    if (client->initialize(mModule) != OK) {
211        return NULL;
212    }
213
214    mClient[cameraId] = client;
215    LOG1("CameraService::connect X (id %d)", cameraId);
216    return client;
217}
218
219void CameraService::removeClient(const sp<ICameraClient>& cameraClient) {
220    int callingPid = getCallingPid();
221    LOG1("CameraService::removeClient E (pid %d)", callingPid);
222
223    for (int i = 0; i < mNumberOfCameras; i++) {
224        // Declare this before the lock to make absolutely sure the
225        // destructor won't be called with the lock held.
226        sp<Client> client;
227
228        Mutex::Autolock lock(mServiceLock);
229
230        // This happens when we have already disconnected (or this is
231        // just another unused camera).
232        if (mClient[i] == 0) continue;
233
234        // Promote mClient. It can fail if we are called from this path:
235        // Client::~Client() -> disconnect() -> removeClient().
236        client = mClient[i].promote();
237
238        if (client == 0) {
239            mClient[i].clear();
240            continue;
241        }
242
243        if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
244            // Found our camera, clear and leave.
245            LOG1("removeClient: clear camera %d", i);
246            mClient[i].clear();
247            break;
248        }
249    }
250
251    LOG1("CameraService::removeClient X (pid %d)", callingPid);
252}
253
254CameraService::Client* CameraService::getClientByIdUnsafe(int cameraId) {
255    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
256    return mClient[cameraId].unsafe_get();
257}
258
259Mutex* CameraService::getClientLockById(int cameraId) {
260    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
261    return &mClientLock[cameraId];
262}
263
264status_t CameraService::onTransact(
265    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
266    // Permission checks
267    switch (code) {
268        case BnCameraService::CONNECT:
269            const int pid = getCallingPid();
270            const int self_pid = getpid();
271            if (pid != self_pid) {
272                // we're called from a different process, do the real check
273                if (!checkCallingPermission(
274                        String16("android.permission.CAMERA"))) {
275                    const int uid = getCallingUid();
276                    ALOGE("Permission Denial: "
277                         "can't use the camera pid=%d, uid=%d", pid, uid);
278                    return PERMISSION_DENIED;
279                }
280            }
281            break;
282    }
283
284    return BnCameraService::onTransact(code, data, reply, flags);
285}
286
287// The reason we need this busy bit is a new CameraService::connect() request
288// may come in while the previous Client's destructor has not been run or is
289// still running. If the last strong reference of the previous Client is gone
290// but the destructor has not been finished, we should not allow the new Client
291// to be created because we need to wait for the previous Client to tear down
292// the hardware first.
293void CameraService::setCameraBusy(int cameraId) {
294    android_atomic_write(1, &mBusy[cameraId]);
295}
296
297void CameraService::setCameraFree(int cameraId) {
298    android_atomic_write(0, &mBusy[cameraId]);
299}
300
301// We share the media players for shutter and recording sound for all clients.
302// A reference count is kept to determine when we will actually release the
303// media players.
304
305MediaPlayer* CameraService::newMediaPlayer(const char *file) {
306    MediaPlayer* mp = new MediaPlayer();
307    if (mp->setDataSource(file, NULL) == NO_ERROR) {
308        mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
309        mp->prepare();
310    } else {
311        ALOGE("Failed to load CameraService sounds: %s", file);
312        return NULL;
313    }
314    return mp;
315}
316
317void CameraService::loadSound() {
318    Mutex::Autolock lock(mSoundLock);
319    LOG1("CameraService::loadSound ref=%d", mSoundRef);
320    if (mSoundRef++) return;
321
322    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
323    mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
324}
325
326void CameraService::releaseSound() {
327    Mutex::Autolock lock(mSoundLock);
328    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
329    if (--mSoundRef) return;
330
331    for (int i = 0; i < NUM_SOUNDS; i++) {
332        if (mSoundPlayer[i] != 0) {
333            mSoundPlayer[i]->disconnect();
334            mSoundPlayer[i].clear();
335        }
336    }
337}
338
339void CameraService::playSound(sound_kind kind) {
340    LOG1("playSound(%d)", kind);
341    Mutex::Autolock lock(mSoundLock);
342    sp<MediaPlayer> player = mSoundPlayer[kind];
343    if (player != 0) {
344        player->seekTo(0);
345        player->start();
346    }
347}
348
349// ----------------------------------------------------------------------------
350
351CameraService::Client::Client(const sp<CameraService>& cameraService,
352        const sp<ICameraClient>& cameraClient,
353        int cameraId, int cameraFacing, int clientPid) {
354    int callingPid = getCallingPid();
355    LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
356
357    mCameraService = cameraService;
358    mCameraClient = cameraClient;
359    mCameraId = cameraId;
360    mCameraFacing = cameraFacing;
361    mClientPid = clientPid;
362    mDestructionStarted = false;
363
364    cameraService->setCameraBusy(cameraId);
365    cameraService->loadSound();
366    LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
367}
368
369// tear down the client
370CameraService::Client::~Client() {
371    mCameraService->releaseSound();
372}
373
374// ----------------------------------------------------------------------------
375
376Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
377    return gCameraService->getClientLockById((int) user);
378}
379
380// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
381// be acquired for this to be safe
382CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
383    Client* client = gCameraService->getClientByIdUnsafe((int) user);
384
385    // This could happen if the Client is in the process of shutting down (the
386    // last strong reference is gone, but the destructor hasn't finished
387    // stopping the hardware).
388    if (client == NULL) return NULL;
389
390    // destruction already started, so should not be accessed
391    if (client->mDestructionStarted) return NULL;
392
393    return client;
394}
395
396void CameraService::Client::disconnect() {
397    mCameraService->removeClient(mCameraClient);
398    mCameraService->setCameraFree(mCameraId);
399}
400
401// ----------------------------------------------------------------------------
402
403static const int kDumpLockRetries = 50;
404static const int kDumpLockSleep = 60000;
405
406static bool tryLock(Mutex& mutex)
407{
408    bool locked = false;
409    for (int i = 0; i < kDumpLockRetries; ++i) {
410        if (mutex.tryLock() == NO_ERROR) {
411            locked = true;
412            break;
413        }
414        usleep(kDumpLockSleep);
415    }
416    return locked;
417}
418
419status_t CameraService::dump(int fd, const Vector<String16>& args) {
420    static const char* kDeadlockedString = "CameraService may be deadlocked\n";
421
422    const size_t SIZE = 256;
423    char buffer[SIZE];
424    String8 result;
425    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
426        snprintf(buffer, SIZE, "Permission Denial: "
427                "can't dump CameraService from pid=%d, uid=%d\n",
428                getCallingPid(),
429                getCallingUid());
430        result.append(buffer);
431        write(fd, result.string(), result.size());
432    } else {
433        bool locked = tryLock(mServiceLock);
434        // failed to lock - CameraService is probably deadlocked
435        if (!locked) {
436            String8 result(kDeadlockedString);
437            write(fd, result.string(), result.size());
438        }
439
440        bool hasClient = false;
441        for (int i = 0; i < mNumberOfCameras; i++) {
442            sp<Client> client = mClient[i].promote();
443            if (client == 0) continue;
444            hasClient = true;
445            client->dump(fd, args);
446        }
447        if (!hasClient) {
448            result.append("No camera client yet.\n");
449            write(fd, result.string(), result.size());
450        }
451
452        if (locked) mServiceLock.unlock();
453
454        // change logging level
455        int n = args.size();
456        for (int i = 0; i + 1 < n; i++) {
457            if (args[i] == String16("-v")) {
458                String8 levelStr(args[i+1]);
459                int level = atoi(levelStr.string());
460                sprintf(buffer, "Set Log Level to %d", level);
461                result.append(buffer);
462                setLogLevel(level);
463            }
464        }
465    }
466    return NO_ERROR;
467}
468
469}; // namespace android
470