CameraService.cpp revision 294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41
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, getpid());
200        break;
201      case CAMERA_DEVICE_API_VERSION_2_0:
202        client = new Camera2Client(this, cameraClient, cameraId,
203                info.facing, callingPid, getpid());
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    cameraClient->asBinder()->linkToDeath(this);
215
216    mClient[cameraId] = client;
217    LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId, getpid());
218    return client;
219}
220
221void CameraService::removeClient(const sp<ICameraClient>& cameraClient) {
222    int callingPid = getCallingPid();
223    LOG1("CameraService::removeClient E (pid %d)", callingPid);
224
225    // Declare this before the lock to make absolutely sure the
226    // destructor won't be called with the lock held.
227    Mutex::Autolock lock(mServiceLock);
228
229    int outIndex;
230    sp<Client> client = findClientUnsafe(cameraClient->asBinder(), outIndex);
231
232    if (client != 0) {
233        // Found our camera, clear and leave.
234        LOG1("removeClient: clear camera %d", outIndex);
235        mClient[outIndex].clear();
236
237        client->unlinkToDeath(this);
238    }
239
240    LOG1("CameraService::removeClient X (pid %d)", callingPid);
241}
242
243sp<CameraService::Client> CameraService::findClientUnsafe(
244                        const wp<IBinder>& cameraClient, int& outIndex) {
245    sp<Client> client;
246
247    for (int i = 0; i < mNumberOfCameras; i++) {
248
249        // This happens when we have already disconnected (or this is
250        // just another unused camera).
251        if (mClient[i] == 0) continue;
252
253        // Promote mClient. It can fail if we are called from this path:
254        // Client::~Client() -> disconnect() -> removeClient().
255        client = mClient[i].promote();
256
257        // Clean up stale client entry
258        if (client == NULL) {
259            mClient[i].clear();
260            continue;
261        }
262
263        if (cameraClient == client->getCameraClient()->asBinder()) {
264            // Found our camera
265            outIndex = i;
266            return client;
267        }
268    }
269
270    outIndex = -1;
271    return NULL;
272}
273
274CameraService::Client* CameraService::getClientByIdUnsafe(int cameraId) {
275    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
276    return mClient[cameraId].unsafe_get();
277}
278
279Mutex* CameraService::getClientLockById(int cameraId) {
280    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
281    return &mClientLock[cameraId];
282}
283
284sp<CameraService::Client> CameraService::getClientByRemote(
285                                const wp<IBinder>& cameraClient) {
286
287    // Declare this before the lock to make absolutely sure the
288    // destructor won't be called with the lock held.
289    sp<Client> client;
290
291    Mutex::Autolock lock(mServiceLock);
292
293    int outIndex;
294    client = findClientUnsafe(cameraClient, outIndex);
295
296    return client;
297}
298
299status_t CameraService::onTransact(
300    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
301    // Permission checks
302    switch (code) {
303        case BnCameraService::CONNECT:
304            const int pid = getCallingPid();
305            const int self_pid = getpid();
306            if (pid != self_pid) {
307                // we're called from a different process, do the real check
308                if (!checkCallingPermission(
309                        String16("android.permission.CAMERA"))) {
310                    const int uid = getCallingUid();
311                    ALOGE("Permission Denial: "
312                         "can't use the camera pid=%d, uid=%d", pid, uid);
313                    return PERMISSION_DENIED;
314                }
315            }
316            break;
317    }
318
319    return BnCameraService::onTransact(code, data, reply, flags);
320}
321
322// The reason we need this busy bit is a new CameraService::connect() request
323// may come in while the previous Client's destructor has not been run or is
324// still running. If the last strong reference of the previous Client is gone
325// but the destructor has not been finished, we should not allow the new Client
326// to be created because we need to wait for the previous Client to tear down
327// the hardware first.
328void CameraService::setCameraBusy(int cameraId) {
329    android_atomic_write(1, &mBusy[cameraId]);
330
331    ALOGV("setCameraBusy cameraId=%d", cameraId);
332}
333
334void CameraService::setCameraFree(int cameraId) {
335    android_atomic_write(0, &mBusy[cameraId]);
336
337    ALOGV("setCameraFree cameraId=%d", cameraId);
338}
339
340// We share the media players for shutter and recording sound for all clients.
341// A reference count is kept to determine when we will actually release the
342// media players.
343
344MediaPlayer* CameraService::newMediaPlayer(const char *file) {
345    MediaPlayer* mp = new MediaPlayer();
346    if (mp->setDataSource(file, NULL) == NO_ERROR) {
347        mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
348        mp->prepare();
349    } else {
350        ALOGE("Failed to load CameraService sounds: %s", file);
351        return NULL;
352    }
353    return mp;
354}
355
356void CameraService::loadSound() {
357    Mutex::Autolock lock(mSoundLock);
358    LOG1("CameraService::loadSound ref=%d", mSoundRef);
359    if (mSoundRef++) return;
360
361    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
362    mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
363}
364
365void CameraService::releaseSound() {
366    Mutex::Autolock lock(mSoundLock);
367    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
368    if (--mSoundRef) return;
369
370    for (int i = 0; i < NUM_SOUNDS; i++) {
371        if (mSoundPlayer[i] != 0) {
372            mSoundPlayer[i]->disconnect();
373            mSoundPlayer[i].clear();
374        }
375    }
376}
377
378void CameraService::playSound(sound_kind kind) {
379    LOG1("playSound(%d)", kind);
380    Mutex::Autolock lock(mSoundLock);
381    sp<MediaPlayer> player = mSoundPlayer[kind];
382    if (player != 0) {
383        player->seekTo(0);
384        player->start();
385    }
386}
387
388// ----------------------------------------------------------------------------
389
390CameraService::Client::Client(const sp<CameraService>& cameraService,
391        const sp<ICameraClient>& cameraClient,
392        int cameraId, int cameraFacing, int clientPid, int servicePid) {
393    int callingPid = getCallingPid();
394    LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
395
396    mCameraService = cameraService;
397    mCameraClient = cameraClient;
398    mCameraId = cameraId;
399    mCameraFacing = cameraFacing;
400    mClientPid = clientPid;
401    mServicePid = servicePid;
402    mDestructionStarted = false;
403
404    cameraService->setCameraBusy(cameraId);
405    cameraService->loadSound();
406    LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
407}
408
409// tear down the client
410CameraService::Client::~Client() {
411    mCameraService->releaseSound();
412}
413
414// ----------------------------------------------------------------------------
415
416Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
417    return gCameraService->getClientLockById((int) user);
418}
419
420// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
421// be acquired for this to be safe
422CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
423    Client* client = gCameraService->getClientByIdUnsafe((int) user);
424
425    // This could happen if the Client is in the process of shutting down (the
426    // last strong reference is gone, but the destructor hasn't finished
427    // stopping the hardware).
428    if (client == NULL) return NULL;
429
430    // destruction already started, so should not be accessed
431    if (client->mDestructionStarted) return NULL;
432
433    return client;
434}
435
436void CameraService::Client::disconnect() {
437    mCameraService->removeClient(mCameraClient);
438    mCameraService->setCameraFree(mCameraId);
439}
440
441// ----------------------------------------------------------------------------
442
443static const int kDumpLockRetries = 50;
444static const int kDumpLockSleep = 60000;
445
446static bool tryLock(Mutex& mutex)
447{
448    bool locked = false;
449    for (int i = 0; i < kDumpLockRetries; ++i) {
450        if (mutex.tryLock() == NO_ERROR) {
451            locked = true;
452            break;
453        }
454        usleep(kDumpLockSleep);
455    }
456    return locked;
457}
458
459status_t CameraService::dump(int fd, const Vector<String16>& args) {
460    String8 result;
461    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
462        result.appendFormat("Permission Denial: "
463                "can't dump CameraService from pid=%d, uid=%d\n",
464                getCallingPid(),
465                getCallingUid());
466        write(fd, result.string(), result.size());
467    } else {
468        bool locked = tryLock(mServiceLock);
469        // failed to lock - CameraService is probably deadlocked
470        if (!locked) {
471            result.append("CameraService may be deadlocked\n");
472            write(fd, result.string(), result.size());
473        }
474
475        bool hasClient = false;
476        if (!mModule) {
477            result = String8::format("No camera module available!\n");
478            write(fd, result.string(), result.size());
479            return NO_ERROR;
480        }
481
482        result = String8::format("Camera module HAL API version: 0x%x\n",
483                mModule->common.hal_api_version);
484        result.appendFormat("Camera module API version: 0x%x\n",
485                mModule->common.module_api_version);
486        result.appendFormat("Camera module name: %s\n",
487                mModule->common.name);
488        result.appendFormat("Camera module author: %s\n",
489                mModule->common.author);
490        result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
491        write(fd, result.string(), result.size());
492        for (int i = 0; i < mNumberOfCameras; i++) {
493            result = String8::format("Camera %d static information:\n", i);
494            camera_info info;
495
496            status_t rc = mModule->get_camera_info(i, &info);
497            if (rc != OK) {
498                result.appendFormat("  Error reading static information!\n");
499                write(fd, result.string(), result.size());
500            } else {
501                result.appendFormat("  Facing: %s\n",
502                        info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
503                result.appendFormat("  Orientation: %d\n", info.orientation);
504                int deviceVersion;
505                if (mModule->common.module_api_version <
506                        CAMERA_MODULE_API_VERSION_2_0) {
507                    deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
508                } else {
509                    deviceVersion = info.device_version;
510                }
511                result.appendFormat("  Device version: 0x%x\n", deviceVersion);
512                if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
513                    result.appendFormat("  Device static metadata:\n");
514                    write(fd, result.string(), result.size());
515                    dump_indented_camera_metadata(info.static_camera_characteristics,
516                            fd, 2, 4);
517                } else {
518                    write(fd, result.string(), result.size());
519                }
520            }
521
522            sp<Client> client = mClient[i].promote();
523            if (client == 0) {
524                result = String8::format("  Device is closed, no client instance\n");
525                write(fd, result.string(), result.size());
526                continue;
527            }
528            hasClient = true;
529            result = String8::format("  Device is open. Client instance dump:\n");
530            write(fd, result.string(), result.size());
531            client->dump(fd, args);
532        }
533        if (!hasClient) {
534            result = String8::format("\nNo active camera clients yet.\n");
535            write(fd, result.string(), result.size());
536        }
537
538        if (locked) mServiceLock.unlock();
539
540        // change logging level
541        int n = args.size();
542        for (int i = 0; i + 1 < n; i++) {
543            String16 verboseOption("-v");
544            if (args[i] == verboseOption) {
545                String8 levelStr(args[i+1]);
546                int level = atoi(levelStr.string());
547                result = String8::format("\nSetting log level to %d.\n", level);
548                setLogLevel(level);
549                write(fd, result.string(), result.size());
550            }
551        }
552
553    }
554    return NO_ERROR;
555}
556
557/*virtual*/void CameraService::binderDied(
558    const wp<IBinder> &who) {
559
560    /**
561      * While tempting to promote the wp<IBinder> into a sp,
562      * it's actually not supported by the binder driver
563      */
564
565    ALOGV("java clients' binder died");
566
567    sp<Client> cameraClient = getClientByRemote(who);
568
569    if (cameraClient == 0) {
570        ALOGV("java clients' binder death already cleaned up (normal case)");
571        return;
572    }
573
574    ALOGW("Disconnecting camera client %p since the binder for it "
575          "died (this pid %d)", cameraClient.get(), getCallingPid());
576
577    cameraClient->disconnect();
578
579}
580
581}; // namespace android
582