CameraService.cpp revision c0dd54f1a77fb94ae69cc3ac5944d718bb6caa28
165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian/*
265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian**
365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** Copyright (C) 2008, The Android Open Source Project
465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian**
565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** Licensed under the Apache License, Version 2.0 (the "License");
665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** you may not use this file except in compliance with the License.
765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** You may obtain a copy of the License at
865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian**
965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian**     http://www.apache.org/licenses/LICENSE-2.0
1065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian**
1165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** Unless required by applicable law or agreed to in writing, software
1265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** distributed under the License is distributed on an "AS IS" BASIS,
1365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** See the License for the specific language governing permissions and
1565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** limitations under the License.
1665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian*/
1765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG_TAG "CameraService"
198951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev//#define LOG_NDEBUG 0
2065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <stdio.h>
2265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <sys/types.h>
2365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <pthread.h>
2465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
2565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IPCThreadState.h>
2665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IServiceManager.h>
2765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/MemoryBase.h>
2865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/MemoryHeapBase.h>
2965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <cutils/atomic.h>
30b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra#include <cutils/properties.h>
31df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/Surface.h>
3265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <hardware/hardware.h>
3365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/AudioSystem.h>
3465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/mediaplayer.h>
3565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Errors.h>
3665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Log.h>
3765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/String16.h>
3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "CameraService.h"
405e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala#include "CameraClient.h"
4161ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala#include "Camera2Client.h"
4265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android {
4465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
4665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Logging support -- this is for debugging only
4765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Use "adb shell dumpsys media.camera -v 1" to change it.
485e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvalavolatile int32_t gLogLevel = 0;
4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
50b8a805261bf0282e992d3608035e47d05a898710Steve Block#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
51b8a805261bf0282e992d3608035e47d05a898710Steve Block#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
5265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic void setLogLevel(int level) {
5465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(level, &gLogLevel);
5565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
5665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
5865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic int getCallingPid() {
6065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return IPCThreadState::self()->getCallingPid();
6165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
6265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic int getCallingUid() {
6465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return IPCThreadState::self()->getCallingUid();
6565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
6665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
6865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// This is ugly and only safe if we never re-create the CameraService, but
7065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// should be ok for now.
7165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic CameraService *gCameraService;
7265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::CameraService()
748951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev:mSoundRef(0), mModule(0)
7565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
76df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("CameraService started (pid=%d)", getpid());
778951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    gCameraService = this;
788951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev}
7965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
808951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchevvoid CameraService::onFirstRef()
818951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev{
828951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    BnCameraService::onFirstRef();
8365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
848951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
858951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev                (const hw_module_t **)&mModule) < 0) {
8629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Could not load camera HAL module");
878951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        mNumberOfCameras = 0;
888951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    }
898951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    else {
90c0dd54f1a77fb94ae69cc3ac5944d718bb6caa28Alex Ray        ALOGI("Loaded \"%s\" camera module", mModule->common.name);
918951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        mNumberOfCameras = mModule->get_number_of_cameras();
928951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        if (mNumberOfCameras > MAX_CAMERAS) {
9329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
948951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev                    mNumberOfCameras, MAX_CAMERAS);
958951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev            mNumberOfCameras = MAX_CAMERAS;
968951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        }
978951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        for (int i = 0; i < mNumberOfCameras; i++) {
988951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev            setCameraFree(i);
998951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        }
10065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
10165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
10265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
10365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::~CameraService() {
10465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < mNumberOfCameras; i++) {
10565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mBusy[i]) {
10629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("camera %d is still in use in destructor!", i);
10765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
10865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
10965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
11065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    gCameraService = NULL;
11165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
11265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
11365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianint32_t CameraService::getNumberOfCameras() {
11465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mNumberOfCameras;
11565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
11665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
11765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::getCameraInfo(int cameraId,
11865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                      struct CameraInfo* cameraInfo) {
1198951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    if (!mModule) {
1208951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        return NO_INIT;
1218951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    }
1228951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
12365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
12465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
12565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
12665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1278951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    struct camera_info info;
1288951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    status_t rc = mModule->get_camera_info(cameraId, &info);
1298951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    cameraInfo->facing = info.facing;
1308951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    cameraInfo->orientation = info.orientation;
1318951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    return rc;
13265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
13365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
13465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<ICamera> CameraService::connect(
13508ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        const sp<ICameraClient>& cameraClient, int cameraId) {
13665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
1375861a9a98c641261c4807c976c750e4611b3a57dTyler Luu
13865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId);
13965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1408951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    if (!mModule) {
14129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Camera HAL module not loaded");
1428951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        return NULL;
1438951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    }
1448951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
14565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<Client> client;
14665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
14729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
14865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            callingPid, cameraId);
14965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NULL;
15065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
15165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
152a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    char value[PROPERTY_VALUE_MAX];
153a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    property_get("sys.secpolicy.camera.disabled", value, "0");
154a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    if (strcmp(value, "1") == 0) {
155a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li        // Camera is disabled by DevicePolicyManager.
156df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
157a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li        return NULL;
158a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    }
159a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li
16065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mServiceLock);
16108ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li    if (mClient[cameraId] != 0) {
16208ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        client = mClient[cameraId].promote();
16308ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        if (client != 0) {
16408ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li            if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
16508ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                LOG1("CameraService::connect X (pid %d) (the same client)",
16608ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                     callingPid);
16708ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                return client;
16808ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li            } else {
16908ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                ALOGW("CameraService::connect X (pid %d) rejected (existing client).",
17008ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                      callingPid);
1712fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li                return NULL;
1722fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li            }
1732fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li        }
17408ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        mClient[cameraId].clear();
17508ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li    }
17608ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li
17708ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li    if (mBusy[cameraId]) {
17808ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        ALOGW("CameraService::connect X (pid %d) rejected"
17908ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                " (camera %d is still busy).", callingPid, cameraId);
18008ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        return NULL;
18165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
18265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1838951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    struct camera_info info;
1848951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    if (mModule->get_camera_info(cameraId, &info) != OK) {
18529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid camera id %d", cameraId);
186b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li        return NULL;
187b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li    }
1888951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
18961ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala    int deviceVersion;
19061ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala    if (mModule->common.module_api_version == CAMERA_MODULE_API_VERSION_2_0) {
19161ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        deviceVersion = info.device_version;
19261ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala    } else {
19361ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
19461ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala    }
19561ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala
19661ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala    switch(deviceVersion) {
197f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala      case CAMERA_DEVICE_API_VERSION_1_0:
198f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala        client = new CameraClient(this, cameraClient, cameraId,
199ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin                info.facing, callingPid, getpid());
20061ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        break;
201f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala      case CAMERA_DEVICE_API_VERSION_2_0:
202f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala        client = new Camera2Client(this, cameraClient, cameraId,
203ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin                info.facing, callingPid, getpid());
20461ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        break;
205f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala      default:
20661ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        ALOGE("Unknown camera device HAL version: %d", deviceVersion);
2075861a9a98c641261c4807c976c750e4611b3a57dTyler Luu        return NULL;
2085861a9a98c641261c4807c976c750e4611b3a57dTyler Luu    }
2095861a9a98c641261c4807c976c750e4611b3a57dTyler Luu
210f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala    if (client->initialize(mModule) != OK) {
211f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala        return NULL;
212f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala    }
213f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala
214ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    cameraClient->asBinder()->linkToDeath(this);
215ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
21665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mClient[cameraId] = client;
217ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId, getpid());
21865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return client;
21965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
22065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
22165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::removeClient(const sp<ICameraClient>& cameraClient) {
22265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
22365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::removeClient E (pid %d)", callingPid);
22465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
225ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    // Declare this before the lock to make absolutely sure the
226ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    // destructor won't be called with the lock held.
227ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    Mutex::Autolock lock(mServiceLock);
228ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
229ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    int outIndex;
230294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin    sp<Client> client = findClientUnsafe(cameraClient->asBinder(), outIndex);
231ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
232ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    if (client != 0) {
233ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        // Found our camera, clear and leave.
234ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        LOG1("removeClient: clear camera %d", outIndex);
235ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        mClient[outIndex].clear();
23665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
237ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        client->unlinkToDeath(this);
238ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    }
239ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
240ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    LOG1("CameraService::removeClient X (pid %d)", callingPid);
241ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin}
242ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
243ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkinsp<CameraService::Client> CameraService::findClientUnsafe(
244294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin                        const wp<IBinder>& cameraClient, int& outIndex) {
245ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    sp<Client> client;
246ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
247ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    for (int i = 0; i < mNumberOfCameras; i++) {
24865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
24965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // This happens when we have already disconnected (or this is
25065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // just another unused camera).
25165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mClient[i] == 0) continue;
25265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
25365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Promote mClient. It can fail if we are called from this path:
25465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Client::~Client() -> disconnect() -> removeClient().
25565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        client = mClient[i].promote();
25665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
257ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        // Clean up stale client entry
258ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        if (client == NULL) {
25965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mClient[i].clear();
26065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            continue;
26165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
26265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
263294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin        if (cameraClient == client->getCameraClient()->asBinder()) {
264ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin            // Found our camera
265ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin            outIndex = i;
266ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin            return client;
26765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
26865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
26965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
270ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    outIndex = -1;
271ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    return NULL;
27265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
27365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
274d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkCameraService::Client* CameraService::getClientByIdUnsafe(int cameraId) {
27565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
276d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    return mClient[cameraId].unsafe_get();
277d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park}
278d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park
279d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkMutex* CameraService::getClientLockById(int cameraId) {
280d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
281d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    return &mClientLock[cameraId];
28265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
28365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
284294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkinsp<CameraService::Client> CameraService::getClientByRemote(
285294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin                                const wp<IBinder>& cameraClient) {
286ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
287ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    // Declare this before the lock to make absolutely sure the
288ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    // destructor won't be called with the lock held.
289ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    sp<Client> client;
290ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
291ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    Mutex::Autolock lock(mServiceLock);
292ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
293ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    int outIndex;
294ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    client = findClientUnsafe(cameraClient, outIndex);
295ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
296ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    return client;
297ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin}
298ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
29965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::onTransact(
30065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
30165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Permission checks
30265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (code) {
30365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case BnCameraService::CONNECT:
30465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            const int pid = getCallingPid();
30565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            const int self_pid = getpid();
30665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (pid != self_pid) {
30765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // we're called from a different process, do the real check
30865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (!checkCallingPermission(
30965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        String16("android.permission.CAMERA"))) {
31065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    const int uid = getCallingUid();
31129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Permission Denial: "
31265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                         "can't use the camera pid=%d, uid=%d", pid, uid);
31365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    return PERMISSION_DENIED;
31465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
31565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
31665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
31765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
31865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BnCameraService::onTransact(code, data, reply, flags);
32065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
32165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
32265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// The reason we need this busy bit is a new CameraService::connect() request
32365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// may come in while the previous Client's destructor has not been run or is
32465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// still running. If the last strong reference of the previous Client is gone
32565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// but the destructor has not been finished, we should not allow the new Client
32665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// to be created because we need to wait for the previous Client to tear down
32765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// the hardware first.
32865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::setCameraBusy(int cameraId) {
32965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(1, &mBusy[cameraId]);
330ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
331ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    ALOGV("setCameraBusy cameraId=%d", cameraId);
33265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
33365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::setCameraFree(int cameraId) {
33565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(0, &mBusy[cameraId]);
336ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
337ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    ALOGV("setCameraFree cameraId=%d", cameraId);
33865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
33965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
34065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// We share the media players for shutter and recording sound for all clients.
34165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// A reference count is kept to determine when we will actually release the
34265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// media players.
34365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
344ff4f55c8d77e276dbcceedb4e560ca1d91ba38baChih-Chung ChangMediaPlayer* CameraService::newMediaPlayer(const char *file) {
34565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    MediaPlayer* mp = new MediaPlayer();
34665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mp->setDataSource(file, NULL) == NO_ERROR) {
34760a78ac9535878984b0777788760b9ee7465c5e6Eino-Ville Talvala        mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
34865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mp->prepare();
34965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
35029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to load CameraService sounds: %s", file);
35165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NULL;
35265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
35365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mp;
35465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
35565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
35665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::loadSound() {
35765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
35865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::loadSound ref=%d", mSoundRef);
35965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mSoundRef++) return;
36065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
36165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
36265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
36365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
36465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
36565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::releaseSound() {
36665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
36765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
36865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (--mSoundRef) return;
36965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < NUM_SOUNDS; i++) {
37165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mSoundPlayer[i] != 0) {
37265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSoundPlayer[i]->disconnect();
37365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSoundPlayer[i].clear();
37465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
37565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
37665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
37765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::playSound(sound_kind kind) {
37965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("playSound(%d)", kind);
38065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
38165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<MediaPlayer> player = mSoundPlayer[kind];
38265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (player != 0) {
3838888a75f01d904541e409e858d23e4150ace34b6Chih-Chung Chang        player->seekTo(0);
3848888a75f01d904541e409e858d23e4150ace34b6Chih-Chung Chang        player->start();
38565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
38665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
38765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
38865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
38965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
39065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::Client(const sp<CameraService>& cameraService,
391b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li        const sp<ICameraClient>& cameraClient,
392ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        int cameraId, int cameraFacing, int clientPid, int servicePid) {
39365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
3942fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li    LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
39565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
39665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraService = cameraService;
39765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraClient = cameraClient;
39865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraId = cameraId;
399e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li    mCameraFacing = cameraFacing;
40065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mClientPid = clientPid;
401ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    mServicePid = servicePid;
402d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    mDestructionStarted = false;
4035e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala
40465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cameraService->setCameraBusy(cameraId);
40565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cameraService->loadSound();
4062fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li    LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
40765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
40865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
40965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// tear down the client
41065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::~Client() {
411f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala    mCameraService->releaseSound();
412036bc3e2cfc5a11c3f7ace41088c8936dae2e946Igor Murashkin
413036bc3e2cfc5a11c3f7ace41088c8936dae2e946Igor Murashkin    // unconditionally disconnect. function is idempotent
414036bc3e2cfc5a11c3f7ace41088c8936dae2e946Igor Murashkin    Client::disconnect();
41565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
41665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
41765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
41865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
419d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkMutex* CameraService::Client::getClientLockFromCookie(void* user) {
420d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    return gCameraService->getClientLockById((int) user);
421d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park}
422d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park
423d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
424d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park// be acquired for this to be safe
425d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkCameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
426d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    Client* client = gCameraService->getClientByIdUnsafe((int) user);
42765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
42865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // This could happen if the Client is in the process of shutting down (the
42965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // last strong reference is gone, but the destructor hasn't finished
43065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // stopping the hardware).
431d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    if (client == NULL) return NULL;
432d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park
433d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    // destruction already started, so should not be accessed
434d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    if (client->mDestructionStarted) return NULL;
43565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
43665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return client;
43765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
43865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
439036bc3e2cfc5a11c3f7ace41088c8936dae2e946Igor Murashkin// NOTE: function is idempotent
4405e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvalavoid CameraService::Client::disconnect() {
4415e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala    mCameraService->removeClient(mCameraClient);
4425e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala    mCameraService->setCameraFree(mCameraId);
443e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li}
444e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li
44565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
44665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
44765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50;
44865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockSleep = 60000;
44965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
45065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic bool tryLock(Mutex& mutex)
45165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
45265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = false;
45365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < kDumpLockRetries; ++i) {
45465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mutex.tryLock() == NO_ERROR) {
45565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            locked = true;
45665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
45765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
45865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        usleep(kDumpLockSleep);
45965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
46065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return locked;
46165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
46265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
46365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::dump(int fd, const Vector<String16>& args) {
46465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
46565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
466611f61998863d3a3ffae4e5f2b723b7319c59ddfEino-Ville Talvala        result.appendFormat("Permission Denial: "
46765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                "can't dump CameraService from pid=%d, uid=%d\n",
46865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                getCallingPid(),
46965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                getCallingUid());
47065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        write(fd, result.string(), result.size());
47165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
47265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool locked = tryLock(mServiceLock);
47365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // failed to lock - CameraService is probably deadlocked
47465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!locked) {
475611f61998863d3a3ffae4e5f2b723b7319c59ddfEino-Ville Talvala            result.append("CameraService may be deadlocked\n");
476f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            write(fd, result.string(), result.size());
47765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
47865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
47965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool hasClient = false;
480f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        if (!mModule) {
481f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            result = String8::format("No camera module available!\n");
482f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            write(fd, result.string(), result.size());
483f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            return NO_ERROR;
484f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        }
485f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala
486f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        result = String8::format("Camera module HAL API version: 0x%x\n",
487f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                mModule->common.hal_api_version);
488f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        result.appendFormat("Camera module API version: 0x%x\n",
489f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                mModule->common.module_api_version);
490f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        result.appendFormat("Camera module name: %s\n",
491f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                mModule->common.name);
492f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        result.appendFormat("Camera module author: %s\n",
493f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                mModule->common.author);
494f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
495f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        write(fd, result.string(), result.size());
49665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (int i = 0; i < mNumberOfCameras; i++) {
497f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            result = String8::format("Camera %d static information:\n", i);
498f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            camera_info info;
499f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala
500f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            status_t rc = mModule->get_camera_info(i, &info);
501f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            if (rc != OK) {
502f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                result.appendFormat("  Error reading static information!\n");
503f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                write(fd, result.string(), result.size());
504f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            } else {
505f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                result.appendFormat("  Facing: %s\n",
506f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                        info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
507f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                result.appendFormat("  Orientation: %d\n", info.orientation);
508f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                int deviceVersion;
509f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                if (mModule->common.module_api_version <
510f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                        CAMERA_MODULE_API_VERSION_2_0) {
511f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                    deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
512f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                } else {
513f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                    deviceVersion = info.device_version;
514f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                }
515f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                result.appendFormat("  Device version: 0x%x\n", deviceVersion);
516f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
517f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                    result.appendFormat("  Device static metadata:\n");
518f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                    write(fd, result.string(), result.size());
519428b77a2b94b74665a47375b3fdb893b98d71269Eino-Ville Talvala                    dump_indented_camera_metadata(info.static_camera_characteristics,
520428b77a2b94b74665a47375b3fdb893b98d71269Eino-Ville Talvala                            fd, 2, 4);
521f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                } else {
522f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                    write(fd, result.string(), result.size());
523f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                }
524f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            }
525f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala
52665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            sp<Client> client = mClient[i].promote();
527f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            if (client == 0) {
528f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                result = String8::format("  Device is closed, no client instance\n");
529f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                write(fd, result.string(), result.size());
530f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                continue;
531f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            }
53265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            hasClient = true;
533f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            result = String8::format("  Device is open. Client instance dump:\n");
534f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            write(fd, result.string(), result.size());
5355e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala            client->dump(fd, args);
53665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
53765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!hasClient) {
538f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            result = String8::format("\nNo active camera clients yet.\n");
539f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            write(fd, result.string(), result.size());
54065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
54165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
54265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (locked) mServiceLock.unlock();
54365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
54465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // change logging level
54565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int n = args.size();
54665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (int i = 0; i + 1 < n; i++) {
547611f61998863d3a3ffae4e5f2b723b7319c59ddfEino-Ville Talvala            String16 verboseOption("-v");
548611f61998863d3a3ffae4e5f2b723b7319c59ddfEino-Ville Talvala            if (args[i] == verboseOption) {
54965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                String8 levelStr(args[i+1]);
55065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                int level = atoi(levelStr.string());
551f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                result = String8::format("\nSetting log level to %d.\n", level);
55265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                setLogLevel(level);
553f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                write(fd, result.string(), result.size());
55465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
55565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
556f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala
55765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
55865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
55965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
56065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
561ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin/*virtual*/void CameraService::binderDied(
562ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    const wp<IBinder> &who) {
563ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
564294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin    /**
565294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin      * While tempting to promote the wp<IBinder> into a sp,
566294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin      * it's actually not supported by the binder driver
567294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin      */
568294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin
569ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    ALOGV("java clients' binder died");
570ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
571294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin    sp<Client> cameraClient = getClientByRemote(who);
572ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
573294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin    if (cameraClient == 0) {
574ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        ALOGV("java clients' binder death already cleaned up (normal case)");
575ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        return;
576ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    }
577ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
578ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    ALOGW("Disconnecting camera client %p since the binder for it "
579ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin          "died (this pid %d)", cameraClient.get(), getCallingPid());
580ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
581ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    cameraClient->disconnect();
582ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
583ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin}
584ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
58565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android
586