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