CameraService.cpp revision 5e08d60617fc63c2e41f9069ff89f5c00db2617d
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"
4365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android {
4565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
4765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Logging support -- this is for debugging only
4865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Use "adb shell dumpsys media.camera -v 1" to change it.
495e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvalavolatile int32_t gLogLevel = 0;
5065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
51b8a805261bf0282e992d3608035e47d05a898710Steve Block#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
52b8a805261bf0282e992d3608035e47d05a898710Steve Block#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
5365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic void setLogLevel(int level) {
5565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(level, &gLogLevel);
5665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
5765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
5965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic int getCallingPid() {
6165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return IPCThreadState::self()->getCallingPid();
6265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
6365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic int getCallingUid() {
6565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return IPCThreadState::self()->getCallingUid();
6665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
6765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
6965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// This is ugly and only safe if we never re-create the CameraService, but
7165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// should be ok for now.
7265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic CameraService *gCameraService;
7365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::CameraService()
758951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev:mSoundRef(0), mModule(0)
7665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
77df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("CameraService started (pid=%d)", getpid());
788951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    gCameraService = this;
798951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev}
8065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
818951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchevvoid CameraService::onFirstRef()
828951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev{
838951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    BnCameraService::onFirstRef();
8465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
858951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
868951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev                (const hw_module_t **)&mModule) < 0) {
8729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Could not load camera HAL module");
888951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        mNumberOfCameras = 0;
898951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    }
908951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    else {
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    sp<CameraHardwareInterface> hardware = NULL;
1385861a9a98c641261c4807c976c750e4611b3a57dTyler Luu
13965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId);
14065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1418951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    if (!mModule) {
14229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Camera HAL module not loaded");
1438951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        return NULL;
1448951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    }
1458951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
14665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<Client> client;
14765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
14829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
14965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            callingPid, cameraId);
15065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NULL;
15165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
15265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
153a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    char value[PROPERTY_VALUE_MAX];
154a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    property_get("sys.secpolicy.camera.disabled", value, "0");
155a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    if (strcmp(value, "1") == 0) {
156a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li        // Camera is disabled by DevicePolicyManager.
157df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
158a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li        return NULL;
159a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    }
160a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li
16165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mServiceLock);
16208ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li    if (mClient[cameraId] != 0) {
16308ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        client = mClient[cameraId].promote();
16408ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        if (client != 0) {
16508ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li            if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
16608ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                LOG1("CameraService::connect X (pid %d) (the same client)",
16708ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                     callingPid);
16808ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                return client;
16908ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li            } else {
17008ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                ALOGW("CameraService::connect X (pid %d) rejected (existing client).",
17108ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                      callingPid);
1722fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li                return NULL;
1732fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li            }
1742fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li        }
17508ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        mClient[cameraId].clear();
17608ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li    }
17708ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li
17808ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li    if (mBusy[cameraId]) {
17908ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        ALOGW("CameraService::connect X (pid %d) rejected"
18008ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                " (camera %d is still busy).", callingPid, cameraId);
18108ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        return NULL;
18265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
18365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1848951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    struct camera_info info;
1858951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    if (mModule->get_camera_info(cameraId, &info) != OK) {
18629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid camera id %d", cameraId);
187b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li        return NULL;
188b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li    }
1898951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
1908951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    char camera_device_name[10];
1918951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    snprintf(camera_device_name, sizeof(camera_device_name), "%d", cameraId);
1928951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
1935861a9a98c641261c4807c976c750e4611b3a57dTyler Luu    hardware = new CameraHardwareInterface(camera_device_name);
1945861a9a98c641261c4807c976c750e4611b3a57dTyler Luu    if (hardware->initialize(&mModule->common) != OK) {
1955861a9a98c641261c4807c976c750e4611b3a57dTyler Luu        hardware.clear();
1965861a9a98c641261c4807c976c750e4611b3a57dTyler Luu        return NULL;
1975861a9a98c641261c4807c976c750e4611b3a57dTyler Luu    }
1985861a9a98c641261c4807c976c750e4611b3a57dTyler Luu
1995e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala    client = new CameraClient(this, cameraClient, hardware, cameraId, info.facing, callingPid);
20065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mClient[cameraId] = client;
2012fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li    LOG1("CameraService::connect X (id %d)", cameraId);
20265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return client;
20365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
20465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
20565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::removeClient(const sp<ICameraClient>& cameraClient) {
20665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
20765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::removeClient E (pid %d)", callingPid);
20865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
20965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < mNumberOfCameras; i++) {
21065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Declare this before the lock to make absolutely sure the
21165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // destructor won't be called with the lock held.
21265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<Client> client;
21365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
21465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock lock(mServiceLock);
21565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
21665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // This happens when we have already disconnected (or this is
21765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // just another unused camera).
21865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mClient[i] == 0) continue;
21965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
22065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Promote mClient. It can fail if we are called from this path:
22165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Client::~Client() -> disconnect() -> removeClient().
22265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        client = mClient[i].promote();
22365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
22465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (client == 0) {
22565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mClient[i].clear();
22665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            continue;
22765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
22865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
22965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
23065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // Found our camera, clear and leave.
23165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            LOG1("removeClient: clear camera %d", i);
23265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mClient[i].clear();
23365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
23465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
23565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
23665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
23765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::removeClient X (pid %d)", callingPid);
23865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
23965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
240d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkCameraService::Client* CameraService::getClientByIdUnsafe(int cameraId) {
24165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
242d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    return mClient[cameraId].unsafe_get();
243d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park}
244d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park
245d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkMutex* CameraService::getClientLockById(int cameraId) {
246d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
247d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    return &mClientLock[cameraId];
24865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
24965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
25065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::onTransact(
25165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
25265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Permission checks
25365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (code) {
25465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case BnCameraService::CONNECT:
25565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            const int pid = getCallingPid();
25665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            const int self_pid = getpid();
25765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (pid != self_pid) {
25865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // we're called from a different process, do the real check
25965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (!checkCallingPermission(
26065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        String16("android.permission.CAMERA"))) {
26165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    const int uid = getCallingUid();
26229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Permission Denial: "
26365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                         "can't use the camera pid=%d, uid=%d", pid, uid);
26465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    return PERMISSION_DENIED;
26565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
26665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
26765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
26865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
26965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
27065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BnCameraService::onTransact(code, data, reply, flags);
27165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
27265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
27365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// The reason we need this busy bit is a new CameraService::connect() request
27465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// may come in while the previous Client's destructor has not been run or is
27565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// still running. If the last strong reference of the previous Client is gone
27665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// but the destructor has not been finished, we should not allow the new Client
27765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// to be created because we need to wait for the previous Client to tear down
27865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// the hardware first.
27965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::setCameraBusy(int cameraId) {
28065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(1, &mBusy[cameraId]);
28165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
28265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
28365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::setCameraFree(int cameraId) {
28465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(0, &mBusy[cameraId]);
28565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
28665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
28765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// We share the media players for shutter and recording sound for all clients.
28865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// A reference count is kept to determine when we will actually release the
28965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// media players.
29065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
291ff4f55c8d77e276dbcceedb4e560ca1d91ba38baChih-Chung ChangMediaPlayer* CameraService::newMediaPlayer(const char *file) {
29265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    MediaPlayer* mp = new MediaPlayer();
29365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mp->setDataSource(file, NULL) == NO_ERROR) {
29460a78ac9535878984b0777788760b9ee7465c5e6Eino-Ville Talvala        mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
29565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mp->prepare();
29665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
29729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to load CameraService sounds: %s", file);
29865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NULL;
29965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
30065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mp;
30165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
30265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
30365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::loadSound() {
30465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
30565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::loadSound ref=%d", mSoundRef);
30665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mSoundRef++) return;
30765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
30865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
30965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
31065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
31165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::releaseSound() {
31365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
31465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
31565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (--mSoundRef) return;
31665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < NUM_SOUNDS; i++) {
31865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mSoundPlayer[i] != 0) {
31965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSoundPlayer[i]->disconnect();
32065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSoundPlayer[i].clear();
32165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
32265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
32365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
32465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
32565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::playSound(sound_kind kind) {
32665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("playSound(%d)", kind);
32765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
32865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<MediaPlayer> player = mSoundPlayer[kind];
32965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (player != 0) {
3308888a75f01d904541e409e858d23e4150ace34b6Chih-Chung Chang        player->seekTo(0);
3318888a75f01d904541e409e858d23e4150ace34b6Chih-Chung Chang        player->start();
33265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
33365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
33465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
33665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::Client(const sp<CameraService>& cameraService,
338b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li        const sp<ICameraClient>& cameraClient,
33908ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        int cameraId, int cameraFacing, int clientPid) {
34065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
3412fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li    LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
34265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
34365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraService = cameraService;
34465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraClient = cameraClient;
34565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraId = cameraId;
346e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li    mCameraFacing = cameraFacing;
34765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mClientPid = clientPid;
348d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    mDestructionStarted = false;
3495e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala
35065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cameraService->setCameraBusy(cameraId);
35165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cameraService->loadSound();
3522fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li    LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
35365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
35465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
35565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// tear down the client
35665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::~Client() {
35765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
35865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
35965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
36065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
361d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkMutex* CameraService::Client::getClientLockFromCookie(void* user) {
362d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    return gCameraService->getClientLockById((int) user);
363d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park}
364d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park
365d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
366d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park// be acquired for this to be safe
367d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkCameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
368d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    Client* client = gCameraService->getClientByIdUnsafe((int) user);
36965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // This could happen if the Client is in the process of shutting down (the
37165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // last strong reference is gone, but the destructor hasn't finished
37265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // stopping the hardware).
373d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    if (client == NULL) return NULL;
374d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park
375d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    // destruction already started, so should not be accessed
376d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    if (client->mDestructionStarted) return NULL;
37765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return client;
37965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
38065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3815e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvalavoid CameraService::Client::disconnect() {
3825e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala    mCameraService->removeClient(mCameraClient);
3835e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala    mCameraService->setCameraFree(mCameraId);
384e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li}
385e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li
38665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
38765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
38865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50;
38965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockSleep = 60000;
39065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
39165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic bool tryLock(Mutex& mutex)
39265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
39365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = false;
39465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < kDumpLockRetries; ++i) {
39565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mutex.tryLock() == NO_ERROR) {
39665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            locked = true;
39765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
39865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
39965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        usleep(kDumpLockSleep);
40065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
40165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return locked;
40265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
40365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
40465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::dump(int fd, const Vector<String16>& args) {
40565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    static const char* kDeadlockedString = "CameraService may be deadlocked\n";
40665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
40765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
40865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
40965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
41065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
41165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        snprintf(buffer, SIZE, "Permission Denial: "
41265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                "can't dump CameraService from pid=%d, uid=%d\n",
41365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                getCallingPid(),
41465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                getCallingUid());
41565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        result.append(buffer);
41665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        write(fd, result.string(), result.size());
41765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
41865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool locked = tryLock(mServiceLock);
41965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // failed to lock - CameraService is probably deadlocked
42065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!locked) {
42165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            String8 result(kDeadlockedString);
42265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
42365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
42465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
42565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool hasClient = false;
42665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (int i = 0; i < mNumberOfCameras; i++) {
42765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            sp<Client> client = mClient[i].promote();
42865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (client == 0) continue;
42965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            hasClient = true;
4305e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala            client->dump(fd, args);
43165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
43265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!hasClient) {
43365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            result.append("No camera client yet.\n");
43465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
43565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
43665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
43765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (locked) mServiceLock.unlock();
43865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
43965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // change logging level
44065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int n = args.size();
44165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (int i = 0; i + 1 < n; i++) {
44265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (args[i] == String16("-v")) {
44365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                String8 levelStr(args[i+1]);
44465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                int level = atoi(levelStr.string());
44565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                sprintf(buffer, "Set Log Level to %d", level);
44665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                result.append(buffer);
44765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                setLogLevel(level);
44865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
44965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
45065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
45165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
45265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
45365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
45465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android
455