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