CameraService.cpp revision 5e08d60617fc63c2e41f9069ff89f5c00db2617d
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 "CameraHardwareInterface.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    sp<CameraHardwareInterface> hardware = NULL;
138
139    LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId);
140
141    if (!mModule) {
142        ALOGE("Camera HAL module not loaded");
143        return NULL;
144    }
145
146    sp<Client> client;
147    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
148        ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
149            callingPid, cameraId);
150        return NULL;
151    }
152
153    char value[PROPERTY_VALUE_MAX];
154    property_get("sys.secpolicy.camera.disabled", value, "0");
155    if (strcmp(value, "1") == 0) {
156        // Camera is disabled by DevicePolicyManager.
157        ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
158        return NULL;
159    }
160
161    Mutex::Autolock lock(mServiceLock);
162    if (mClient[cameraId] != 0) {
163        client = mClient[cameraId].promote();
164        if (client != 0) {
165            if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
166                LOG1("CameraService::connect X (pid %d) (the same client)",
167                     callingPid);
168                return client;
169            } else {
170                ALOGW("CameraService::connect X (pid %d) rejected (existing client).",
171                      callingPid);
172                return NULL;
173            }
174        }
175        mClient[cameraId].clear();
176    }
177
178    if (mBusy[cameraId]) {
179        ALOGW("CameraService::connect X (pid %d) rejected"
180                " (camera %d is still busy).", callingPid, cameraId);
181        return NULL;
182    }
183
184    struct camera_info info;
185    if (mModule->get_camera_info(cameraId, &info) != OK) {
186        ALOGE("Invalid camera id %d", cameraId);
187        return NULL;
188    }
189
190    char camera_device_name[10];
191    snprintf(camera_device_name, sizeof(camera_device_name), "%d", cameraId);
192
193    hardware = new CameraHardwareInterface(camera_device_name);
194    if (hardware->initialize(&mModule->common) != OK) {
195        hardware.clear();
196        return NULL;
197    }
198
199    client = new CameraClient(this, cameraClient, hardware, cameraId, info.facing, callingPid);
200    mClient[cameraId] = client;
201    LOG1("CameraService::connect X (id %d)", cameraId);
202    return client;
203}
204
205void CameraService::removeClient(const sp<ICameraClient>& cameraClient) {
206    int callingPid = getCallingPid();
207    LOG1("CameraService::removeClient E (pid %d)", callingPid);
208
209    for (int i = 0; i < mNumberOfCameras; i++) {
210        // Declare this before the lock to make absolutely sure the
211        // destructor won't be called with the lock held.
212        sp<Client> client;
213
214        Mutex::Autolock lock(mServiceLock);
215
216        // This happens when we have already disconnected (or this is
217        // just another unused camera).
218        if (mClient[i] == 0) continue;
219
220        // Promote mClient. It can fail if we are called from this path:
221        // Client::~Client() -> disconnect() -> removeClient().
222        client = mClient[i].promote();
223
224        if (client == 0) {
225            mClient[i].clear();
226            continue;
227        }
228
229        if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
230            // Found our camera, clear and leave.
231            LOG1("removeClient: clear camera %d", i);
232            mClient[i].clear();
233            break;
234        }
235    }
236
237    LOG1("CameraService::removeClient X (pid %d)", callingPid);
238}
239
240CameraService::Client* CameraService::getClientByIdUnsafe(int cameraId) {
241    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
242    return mClient[cameraId].unsafe_get();
243}
244
245Mutex* CameraService::getClientLockById(int cameraId) {
246    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
247    return &mClientLock[cameraId];
248}
249
250status_t CameraService::onTransact(
251    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
252    // Permission checks
253    switch (code) {
254        case BnCameraService::CONNECT:
255            const int pid = getCallingPid();
256            const int self_pid = getpid();
257            if (pid != self_pid) {
258                // we're called from a different process, do the real check
259                if (!checkCallingPermission(
260                        String16("android.permission.CAMERA"))) {
261                    const int uid = getCallingUid();
262                    ALOGE("Permission Denial: "
263                         "can't use the camera pid=%d, uid=%d", pid, uid);
264                    return PERMISSION_DENIED;
265                }
266            }
267            break;
268    }
269
270    return BnCameraService::onTransact(code, data, reply, flags);
271}
272
273// The reason we need this busy bit is a new CameraService::connect() request
274// may come in while the previous Client's destructor has not been run or is
275// still running. If the last strong reference of the previous Client is gone
276// but the destructor has not been finished, we should not allow the new Client
277// to be created because we need to wait for the previous Client to tear down
278// the hardware first.
279void CameraService::setCameraBusy(int cameraId) {
280    android_atomic_write(1, &mBusy[cameraId]);
281}
282
283void CameraService::setCameraFree(int cameraId) {
284    android_atomic_write(0, &mBusy[cameraId]);
285}
286
287// We share the media players for shutter and recording sound for all clients.
288// A reference count is kept to determine when we will actually release the
289// media players.
290
291MediaPlayer* CameraService::newMediaPlayer(const char *file) {
292    MediaPlayer* mp = new MediaPlayer();
293    if (mp->setDataSource(file, NULL) == NO_ERROR) {
294        mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
295        mp->prepare();
296    } else {
297        ALOGE("Failed to load CameraService sounds: %s", file);
298        return NULL;
299    }
300    return mp;
301}
302
303void CameraService::loadSound() {
304    Mutex::Autolock lock(mSoundLock);
305    LOG1("CameraService::loadSound ref=%d", mSoundRef);
306    if (mSoundRef++) return;
307
308    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
309    mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
310}
311
312void CameraService::releaseSound() {
313    Mutex::Autolock lock(mSoundLock);
314    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
315    if (--mSoundRef) return;
316
317    for (int i = 0; i < NUM_SOUNDS; i++) {
318        if (mSoundPlayer[i] != 0) {
319            mSoundPlayer[i]->disconnect();
320            mSoundPlayer[i].clear();
321        }
322    }
323}
324
325void CameraService::playSound(sound_kind kind) {
326    LOG1("playSound(%d)", kind);
327    Mutex::Autolock lock(mSoundLock);
328    sp<MediaPlayer> player = mSoundPlayer[kind];
329    if (player != 0) {
330        player->seekTo(0);
331        player->start();
332    }
333}
334
335// ----------------------------------------------------------------------------
336
337CameraService::Client::Client(const sp<CameraService>& cameraService,
338        const sp<ICameraClient>& cameraClient,
339        int cameraId, int cameraFacing, int clientPid) {
340    int callingPid = getCallingPid();
341    LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
342
343    mCameraService = cameraService;
344    mCameraClient = cameraClient;
345    mCameraId = cameraId;
346    mCameraFacing = cameraFacing;
347    mClientPid = clientPid;
348    mDestructionStarted = false;
349
350    cameraService->setCameraBusy(cameraId);
351    cameraService->loadSound();
352    LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
353}
354
355// tear down the client
356CameraService::Client::~Client() {
357}
358
359// ----------------------------------------------------------------------------
360
361Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
362    return gCameraService->getClientLockById((int) user);
363}
364
365// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
366// be acquired for this to be safe
367CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
368    Client* client = gCameraService->getClientByIdUnsafe((int) user);
369
370    // This could happen if the Client is in the process of shutting down (the
371    // last strong reference is gone, but the destructor hasn't finished
372    // stopping the hardware).
373    if (client == NULL) return NULL;
374
375    // destruction already started, so should not be accessed
376    if (client->mDestructionStarted) return NULL;
377
378    return client;
379}
380
381void CameraService::Client::disconnect() {
382    mCameraService->removeClient(mCameraClient);
383    mCameraService->setCameraFree(mCameraId);
384}
385
386// ----------------------------------------------------------------------------
387
388static const int kDumpLockRetries = 50;
389static const int kDumpLockSleep = 60000;
390
391static bool tryLock(Mutex& mutex)
392{
393    bool locked = false;
394    for (int i = 0; i < kDumpLockRetries; ++i) {
395        if (mutex.tryLock() == NO_ERROR) {
396            locked = true;
397            break;
398        }
399        usleep(kDumpLockSleep);
400    }
401    return locked;
402}
403
404status_t CameraService::dump(int fd, const Vector<String16>& args) {
405    static const char* kDeadlockedString = "CameraService may be deadlocked\n";
406
407    const size_t SIZE = 256;
408    char buffer[SIZE];
409    String8 result;
410    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
411        snprintf(buffer, SIZE, "Permission Denial: "
412                "can't dump CameraService from pid=%d, uid=%d\n",
413                getCallingPid(),
414                getCallingUid());
415        result.append(buffer);
416        write(fd, result.string(), result.size());
417    } else {
418        bool locked = tryLock(mServiceLock);
419        // failed to lock - CameraService is probably deadlocked
420        if (!locked) {
421            String8 result(kDeadlockedString);
422            write(fd, result.string(), result.size());
423        }
424
425        bool hasClient = false;
426        for (int i = 0; i < mNumberOfCameras; i++) {
427            sp<Client> client = mClient[i].promote();
428            if (client == 0) continue;
429            hasClient = true;
430            client->dump(fd, args);
431        }
432        if (!hasClient) {
433            result.append("No camera client yet.\n");
434            write(fd, result.string(), result.size());
435        }
436
437        if (locked) mServiceLock.unlock();
438
439        // change logging level
440        int n = args.size();
441        for (int i = 0; i + 1 < n; i++) {
442            if (args[i] == String16("-v")) {
443                String8 levelStr(args[i+1]);
444                int level = atoi(levelStr.string());
445                sprintf(buffer, "Set Log Level to %d", level);
446                result.append(buffer);
447                setLogLevel(level);
448            }
449        }
450    }
451    return NO_ERROR;
452}
453
454}; // namespace android
455