CameraService.cpp revision 61ab9f93315ea817cd1ac110e2a95da4dab6b4d1
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>
31bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis#include <gui/SurfaceTextureClient.h>
32df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/Surface.h>
3365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <hardware/hardware.h>
3465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/AudioSystem.h>
3565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/mediaplayer.h>
3665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Errors.h>
3765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Log.h>
3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/String16.h>
3965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "CameraService.h"
415e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala#include "CameraClient.h"
428951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev#include "CameraHardwareInterface.h"
4361ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala#include "Camera2Client.h"
4461ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala#include "Camera2Device.h"
4565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android {
4765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Logging support -- this is for debugging only
5065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Use "adb shell dumpsys media.camera -v 1" to change it.
515e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvalavolatile int32_t gLogLevel = 0;
5265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
53b8a805261bf0282e992d3608035e47d05a898710Steve Block#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
54b8a805261bf0282e992d3608035e47d05a898710Steve Block#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
5565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic void setLogLevel(int level) {
5765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(level, &gLogLevel);
5865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
5965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
6165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic int getCallingPid() {
6365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return IPCThreadState::self()->getCallingPid();
6465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
6565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic int getCallingUid() {
6765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return IPCThreadState::self()->getCallingUid();
6865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
6965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
7165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// This is ugly and only safe if we never re-create the CameraService, but
7365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// should be ok for now.
7465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic CameraService *gCameraService;
7565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::CameraService()
778951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev:mSoundRef(0), mModule(0)
7865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
79df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("CameraService started (pid=%d)", getpid());
808951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    gCameraService = this;
818951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev}
8265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
838951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchevvoid CameraService::onFirstRef()
848951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev{
858951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    BnCameraService::onFirstRef();
8665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
878951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
888951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev                (const hw_module_t **)&mModule) < 0) {
8929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Could not load camera HAL module");
908951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        mNumberOfCameras = 0;
918951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    }
928951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    else {
938951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        mNumberOfCameras = mModule->get_number_of_cameras();
948951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        if (mNumberOfCameras > MAX_CAMERAS) {
9529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
968951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev                    mNumberOfCameras, MAX_CAMERAS);
978951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev            mNumberOfCameras = MAX_CAMERAS;
988951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        }
998951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        for (int i = 0; i < mNumberOfCameras; i++) {
1008951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev            setCameraFree(i);
1018951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        }
10265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
10365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
10465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
10565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::~CameraService() {
10665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < mNumberOfCameras; i++) {
10765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mBusy[i]) {
10829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("camera %d is still in use in destructor!", i);
10965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
11065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
11165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
11265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    gCameraService = NULL;
11365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
11465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
11565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianint32_t CameraService::getNumberOfCameras() {
11665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mNumberOfCameras;
11765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
11865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
11965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::getCameraInfo(int cameraId,
12065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                      struct CameraInfo* cameraInfo) {
1218951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    if (!mModule) {
1228951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        return NO_INIT;
1238951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    }
1248951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
12565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
12665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
12765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
12865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1298951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    struct camera_info info;
1308951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    status_t rc = mModule->get_camera_info(cameraId, &info);
1318951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    cameraInfo->facing = info.facing;
1328951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    cameraInfo->orientation = info.orientation;
1338951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    return rc;
13465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
13565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
13665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<ICamera> CameraService::connect(
13708ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        const sp<ICameraClient>& cameraClient, int cameraId) {
13865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
1395861a9a98c641261c4807c976c750e4611b3a57dTyler Luu
14065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId);
14165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1428951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    if (!mModule) {
14329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Camera HAL module not loaded");
1448951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        return NULL;
1458951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    }
1468951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
14765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<Client> client;
14865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
14929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
15065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            callingPid, cameraId);
15165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NULL;
15265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
15365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
154a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    char value[PROPERTY_VALUE_MAX];
155a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    property_get("sys.secpolicy.camera.disabled", value, "0");
156a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    if (strcmp(value, "1") == 0) {
157a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li        // Camera is disabled by DevicePolicyManager.
158df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
159a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li        return NULL;
160a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    }
161a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li
16265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mServiceLock);
16308ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li    if (mClient[cameraId] != 0) {
16408ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        client = mClient[cameraId].promote();
16508ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        if (client != 0) {
16608ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li            if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
16708ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                LOG1("CameraService::connect X (pid %d) (the same client)",
16808ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                     callingPid);
16908ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                return client;
17008ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li            } else {
17108ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                ALOGW("CameraService::connect X (pid %d) rejected (existing client).",
17208ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                      callingPid);
1732fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li                return NULL;
1742fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li            }
1752fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li        }
17608ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        mClient[cameraId].clear();
17708ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li    }
17808ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li
17908ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li    if (mBusy[cameraId]) {
18008ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        ALOGW("CameraService::connect X (pid %d) rejected"
18108ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                " (camera %d is still busy).", callingPid, cameraId);
18208ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        return NULL;
18365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
18465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1858951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    struct camera_info info;
1868951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    if (mModule->get_camera_info(cameraId, &info) != OK) {
18729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid camera id %d", cameraId);
188b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li        return NULL;
189b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li    }
1908951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
1918951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    char camera_device_name[10];
1928951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    snprintf(camera_device_name, sizeof(camera_device_name), "%d", cameraId);
1938951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
19461ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala    int deviceVersion;
19561ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala    if (mModule->common.module_api_version == CAMERA_MODULE_API_VERSION_2_0) {
19661ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        deviceVersion = info.device_version;
19761ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala    } else {
19861ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
19961ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala    }
20061ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala
20161ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala    switch(deviceVersion) {
20261ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala    case CAMERA_DEVICE_API_VERSION_1_0: {
20361ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        sp<CameraHardwareInterface> hardware =
20461ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala            new CameraHardwareInterface(camera_device_name);
20561ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        if (hardware->initialize(&mModule->common) != OK) {
20661ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala            return NULL;
20761ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        }
20861ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala
20961ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        client = new CameraClient(this, cameraClient, hardware, cameraId,
21061ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala                info.facing, callingPid);
21161ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        break;
21261ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala    }
21361ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala    case CAMERA_DEVICE_API_VERSION_2_0: {
21461ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        sp<Camera2Device> hardware =
21561ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala            new Camera2Device(camera_device_name);
21661ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        if (hardware->initialize(&mModule->common) != OK) {
21761ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala            return NULL;
21861ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        }
21961ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala
22061ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        client = new Camera2Client(this, cameraClient, hardware, cameraId,
22161ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala                info.facing, callingPid);
22261ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        break;
22361ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala    }
22461ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala    default:
22561ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        ALOGE("Unknown camera device HAL version: %d", deviceVersion);
2265861a9a98c641261c4807c976c750e4611b3a57dTyler Luu        return NULL;
2275861a9a98c641261c4807c976c750e4611b3a57dTyler Luu    }
2285861a9a98c641261c4807c976c750e4611b3a57dTyler Luu
22965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mClient[cameraId] = client;
2302fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li    LOG1("CameraService::connect X (id %d)", cameraId);
23165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return client;
23265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
23365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
23465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::removeClient(const sp<ICameraClient>& cameraClient) {
23565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
23665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::removeClient E (pid %d)", callingPid);
23765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
23865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < mNumberOfCameras; i++) {
23965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Declare this before the lock to make absolutely sure the
24065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // destructor won't be called with the lock held.
24165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<Client> client;
24265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
24365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock lock(mServiceLock);
24465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
24565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // This happens when we have already disconnected (or this is
24665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // just another unused camera).
24765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mClient[i] == 0) continue;
24865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
24965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Promote mClient. It can fail if we are called from this path:
25065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Client::~Client() -> disconnect() -> removeClient().
25165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        client = mClient[i].promote();
25265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
25365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (client == 0) {
25465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mClient[i].clear();
25565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            continue;
25665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
25765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
25865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
25965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // Found our camera, clear and leave.
26065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            LOG1("removeClient: clear camera %d", i);
26165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mClient[i].clear();
26265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
26365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
26465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
26565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
26665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::removeClient X (pid %d)", callingPid);
26765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
26865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
269d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkCameraService::Client* CameraService::getClientByIdUnsafe(int cameraId) {
27065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
271d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    return mClient[cameraId].unsafe_get();
272d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park}
273d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park
274d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkMutex* CameraService::getClientLockById(int cameraId) {
275d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
276d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    return &mClientLock[cameraId];
27765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
27865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
27965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::onTransact(
28065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
28165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Permission checks
28265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (code) {
28365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case BnCameraService::CONNECT:
28465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            const int pid = getCallingPid();
28565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            const int self_pid = getpid();
28665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (pid != self_pid) {
28765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // we're called from a different process, do the real check
28865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (!checkCallingPermission(
28965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        String16("android.permission.CAMERA"))) {
29065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    const int uid = getCallingUid();
29129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Permission Denial: "
29265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                         "can't use the camera pid=%d, uid=%d", pid, uid);
29365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    return PERMISSION_DENIED;
29465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
29565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
29665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
29765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
29865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
29965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BnCameraService::onTransact(code, data, reply, flags);
30065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
30165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
30265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// The reason we need this busy bit is a new CameraService::connect() request
30365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// may come in while the previous Client's destructor has not been run or is
30465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// still running. If the last strong reference of the previous Client is gone
30565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// but the destructor has not been finished, we should not allow the new Client
30665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// to be created because we need to wait for the previous Client to tear down
30765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// the hardware first.
30865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::setCameraBusy(int cameraId) {
30965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(1, &mBusy[cameraId]);
31065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
31165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::setCameraFree(int cameraId) {
31365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(0, &mBusy[cameraId]);
31465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
31565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// We share the media players for shutter and recording sound for all clients.
31765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// A reference count is kept to determine when we will actually release the
31865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// media players.
31965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
320ff4f55c8d77e276dbcceedb4e560ca1d91ba38baChih-Chung ChangMediaPlayer* CameraService::newMediaPlayer(const char *file) {
32165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    MediaPlayer* mp = new MediaPlayer();
32265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mp->setDataSource(file, NULL) == NO_ERROR) {
32360a78ac9535878984b0777788760b9ee7465c5e6Eino-Ville Talvala        mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
32465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mp->prepare();
32565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
32629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to load CameraService sounds: %s", file);
32765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NULL;
32865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
32965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mp;
33065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
33165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::loadSound() {
33365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
33465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::loadSound ref=%d", mSoundRef);
33565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mSoundRef++) return;
33665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
33865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
33965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
34065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
34165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::releaseSound() {
34265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
34365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
34465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (--mSoundRef) return;
34565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
34665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < NUM_SOUNDS; i++) {
34765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mSoundPlayer[i] != 0) {
34865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSoundPlayer[i]->disconnect();
34965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSoundPlayer[i].clear();
35065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
35165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
35265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
35365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
35465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::playSound(sound_kind kind) {
35565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("playSound(%d)", kind);
35665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
35765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<MediaPlayer> player = mSoundPlayer[kind];
35865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (player != 0) {
3598888a75f01d904541e409e858d23e4150ace34b6Chih-Chung Chang        player->seekTo(0);
3608888a75f01d904541e409e858d23e4150ace34b6Chih-Chung Chang        player->start();
36165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
36265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
36365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
36465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
36565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
36665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::Client(const sp<CameraService>& cameraService,
367b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li        const sp<ICameraClient>& cameraClient,
36808ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        int cameraId, int cameraFacing, int clientPid) {
36965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
3702fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li    LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
37165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraService = cameraService;
37365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraClient = cameraClient;
37465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraId = cameraId;
375e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li    mCameraFacing = cameraFacing;
37665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mClientPid = clientPid;
377d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    mDestructionStarted = false;
3785e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala
37965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cameraService->setCameraBusy(cameraId);
38065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cameraService->loadSound();
3812fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li    LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
38265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
38365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
38465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// tear down the client
38565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::~Client() {
38665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
38765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
38865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
38965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
390d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkMutex* CameraService::Client::getClientLockFromCookie(void* user) {
391d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    return gCameraService->getClientLockById((int) user);
392d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park}
393d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park
394d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
395d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park// be acquired for this to be safe
396d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkCameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
397d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    Client* client = gCameraService->getClientByIdUnsafe((int) user);
39865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
39965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // This could happen if the Client is in the process of shutting down (the
40065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // last strong reference is gone, but the destructor hasn't finished
40165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // stopping the hardware).
402d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    if (client == NULL) return NULL;
403d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park
404d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    // destruction already started, so should not be accessed
405d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    if (client->mDestructionStarted) return NULL;
40665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
40765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return client;
40865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
40965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4105e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvalavoid CameraService::Client::disconnect() {
4115e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala    mCameraService->removeClient(mCameraClient);
4125e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala    mCameraService->setCameraFree(mCameraId);
413e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li}
414e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li
41565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
41665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
41765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50;
41865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockSleep = 60000;
41965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
42065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic bool tryLock(Mutex& mutex)
42165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
42265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = false;
42365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < kDumpLockRetries; ++i) {
42465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mutex.tryLock() == NO_ERROR) {
42565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            locked = true;
42665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
42765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
42865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        usleep(kDumpLockSleep);
42965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
43065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return locked;
43165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
43265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
43365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::dump(int fd, const Vector<String16>& args) {
43465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    static const char* kDeadlockedString = "CameraService may be deadlocked\n";
43565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
43665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
43765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
43865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
43965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
44065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        snprintf(buffer, SIZE, "Permission Denial: "
44165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                "can't dump CameraService from pid=%d, uid=%d\n",
44265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                getCallingPid(),
44365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                getCallingUid());
44465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        result.append(buffer);
44565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        write(fd, result.string(), result.size());
44665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
44765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool locked = tryLock(mServiceLock);
44865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // failed to lock - CameraService is probably deadlocked
44965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!locked) {
45065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            String8 result(kDeadlockedString);
45165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
45265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
45365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
45465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool hasClient = false;
45565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (int i = 0; i < mNumberOfCameras; i++) {
45665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            sp<Client> client = mClient[i].promote();
45765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (client == 0) continue;
45865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            hasClient = true;
4595e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala            client->dump(fd, args);
46065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
46165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!hasClient) {
46265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            result.append("No camera client yet.\n");
46365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
46465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
46565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
46665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (locked) mServiceLock.unlock();
46765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
46865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // change logging level
46965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int n = args.size();
47065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (int i = 0; i + 1 < n; i++) {
47165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (args[i] == String16("-v")) {
47265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                String8 levelStr(args[i+1]);
47365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                int level = atoi(levelStr.string());
47465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                sprintf(buffer, "Set Log Level to %d", level);
47565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                result.append(buffer);
47665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                setLogLevel(level);
47765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
47865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
47965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
48065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
48165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
48265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
48365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android
484