CameraService.cpp revision f5926136ad328e95a79336b051d6f853443eaab9
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"
4261ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala#include "Camera2Client.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
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,
19961ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala                info.facing, callingPid);
20061ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        break;
201f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala      case CAMERA_DEVICE_API_VERSION_2_0:
202f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala        client = new Camera2Client(this, cameraClient, cameraId,
20361ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala                info.facing, callingPid);
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
21465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mClient[cameraId] = client;
2152fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li    LOG1("CameraService::connect X (id %d)", cameraId);
21665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return client;
21765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
21865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
21965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::removeClient(const sp<ICameraClient>& cameraClient) {
22065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
22165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::removeClient E (pid %d)", callingPid);
22265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
22365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < mNumberOfCameras; i++) {
22465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Declare this before the lock to make absolutely sure the
22565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // destructor won't be called with the lock held.
22665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<Client> client;
22765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
22865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock lock(mServiceLock);
22965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
23065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // This happens when we have already disconnected (or this is
23165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // just another unused camera).
23265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mClient[i] == 0) continue;
23365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
23465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Promote mClient. It can fail if we are called from this path:
23565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Client::~Client() -> disconnect() -> removeClient().
23665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        client = mClient[i].promote();
23765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
23865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (client == 0) {
23965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mClient[i].clear();
24065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            continue;
24165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
24265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
24365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
24465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // Found our camera, clear and leave.
24565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            LOG1("removeClient: clear camera %d", i);
24665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mClient[i].clear();
24765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
24865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
24965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
25065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
25165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::removeClient X (pid %d)", callingPid);
25265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
25365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
254d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkCameraService::Client* CameraService::getClientByIdUnsafe(int cameraId) {
25565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
256d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    return mClient[cameraId].unsafe_get();
257d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park}
258d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park
259d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkMutex* CameraService::getClientLockById(int cameraId) {
260d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
261d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    return &mClientLock[cameraId];
26265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
26365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
26465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::onTransact(
26565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
26665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Permission checks
26765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (code) {
26865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case BnCameraService::CONNECT:
26965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            const int pid = getCallingPid();
27065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            const int self_pid = getpid();
27165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (pid != self_pid) {
27265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // we're called from a different process, do the real check
27365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (!checkCallingPermission(
27465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        String16("android.permission.CAMERA"))) {
27565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    const int uid = getCallingUid();
27629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Permission Denial: "
27765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                         "can't use the camera pid=%d, uid=%d", pid, uid);
27865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    return PERMISSION_DENIED;
27965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
28065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
28165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
28265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
28365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
28465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BnCameraService::onTransact(code, data, reply, flags);
28565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
28665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
28765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// The reason we need this busy bit is a new CameraService::connect() request
28865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// may come in while the previous Client's destructor has not been run or is
28965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// still running. If the last strong reference of the previous Client is gone
29065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// but the destructor has not been finished, we should not allow the new Client
29165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// to be created because we need to wait for the previous Client to tear down
29265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// the hardware first.
29365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::setCameraBusy(int cameraId) {
29465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(1, &mBusy[cameraId]);
29565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
29665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
29765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::setCameraFree(int cameraId) {
29865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(0, &mBusy[cameraId]);
29965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
30065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
30165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// We share the media players for shutter and recording sound for all clients.
30265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// A reference count is kept to determine when we will actually release the
30365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// media players.
30465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
305ff4f55c8d77e276dbcceedb4e560ca1d91ba38baChih-Chung ChangMediaPlayer* CameraService::newMediaPlayer(const char *file) {
30665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    MediaPlayer* mp = new MediaPlayer();
30765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mp->setDataSource(file, NULL) == NO_ERROR) {
30860a78ac9535878984b0777788760b9ee7465c5e6Eino-Ville Talvala        mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
30965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mp->prepare();
31065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
31129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to load CameraService sounds: %s", file);
31265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NULL;
31365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
31465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mp;
31565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
31665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::loadSound() {
31865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
31965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::loadSound ref=%d", mSoundRef);
32065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mSoundRef++) return;
32165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
32265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
32365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
32465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
32565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
32665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::releaseSound() {
32765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
32865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
32965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (--mSoundRef) return;
33065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < NUM_SOUNDS; i++) {
33265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mSoundPlayer[i] != 0) {
33365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSoundPlayer[i]->disconnect();
33465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSoundPlayer[i].clear();
33565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
33665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
33765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
33865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::playSound(sound_kind kind) {
34065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("playSound(%d)", kind);
34165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
34265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<MediaPlayer> player = mSoundPlayer[kind];
34365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (player != 0) {
3448888a75f01d904541e409e858d23e4150ace34b6Chih-Chung Chang        player->seekTo(0);
3458888a75f01d904541e409e858d23e4150ace34b6Chih-Chung Chang        player->start();
34665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
34765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
34865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
34965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
35065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
35165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::Client(const sp<CameraService>& cameraService,
352b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li        const sp<ICameraClient>& cameraClient,
35308ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        int cameraId, int cameraFacing, int clientPid) {
35465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
3552fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li    LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
35665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
35765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraService = cameraService;
35865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraClient = cameraClient;
35965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraId = cameraId;
360e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li    mCameraFacing = cameraFacing;
36165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mClientPid = clientPid;
362d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    mDestructionStarted = false;
3635e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala
36465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cameraService->setCameraBusy(cameraId);
36565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cameraService->loadSound();
3662fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li    LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
36765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
36865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
36965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// tear down the client
37065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::~Client() {
371f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala    mCameraService->releaseSound();
37265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
37365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
37565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
376d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkMutex* CameraService::Client::getClientLockFromCookie(void* user) {
377d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    return gCameraService->getClientLockById((int) user);
378d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park}
379d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park
380d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
381d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park// be acquired for this to be safe
382d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkCameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
383d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    Client* client = gCameraService->getClientByIdUnsafe((int) user);
38465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
38565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // This could happen if the Client is in the process of shutting down (the
38665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // last strong reference is gone, but the destructor hasn't finished
38765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // stopping the hardware).
388d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    if (client == NULL) return NULL;
389d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park
390d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    // destruction already started, so should not be accessed
391d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    if (client->mDestructionStarted) return NULL;
39265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
39365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return client;
39465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
39565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3965e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvalavoid CameraService::Client::disconnect() {
3975e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala    mCameraService->removeClient(mCameraClient);
3985e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala    mCameraService->setCameraFree(mCameraId);
399e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li}
400e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li
40165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
40265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
40365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50;
40465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockSleep = 60000;
40565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
40665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic bool tryLock(Mutex& mutex)
40765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
40865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = false;
40965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < kDumpLockRetries; ++i) {
41065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mutex.tryLock() == NO_ERROR) {
41165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            locked = true;
41265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
41365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
41465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        usleep(kDumpLockSleep);
41565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
41665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return locked;
41765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
41865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
41965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::dump(int fd, const Vector<String16>& args) {
42065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
42165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
422611f61998863d3a3ffae4e5f2b723b7319c59ddfEino-Ville Talvala        result.appendFormat("Permission Denial: "
42365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                "can't dump CameraService from pid=%d, uid=%d\n",
42465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                getCallingPid(),
42565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                getCallingUid());
42665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        write(fd, result.string(), result.size());
42765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
42865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool locked = tryLock(mServiceLock);
42965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // failed to lock - CameraService is probably deadlocked
43065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!locked) {
431611f61998863d3a3ffae4e5f2b723b7319c59ddfEino-Ville Talvala            result.append("CameraService may be deadlocked\n");
432f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            write(fd, result.string(), result.size());
43365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
43465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
43565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool hasClient = false;
436f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        if (!mModule) {
437f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            result = String8::format("No camera module available!\n");
438f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            write(fd, result.string(), result.size());
439f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            return NO_ERROR;
440f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        }
441f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala
442f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        result = String8::format("Camera module HAL API version: 0x%x\n",
443f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                mModule->common.hal_api_version);
444f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        result.appendFormat("Camera module API version: 0x%x\n",
445f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                mModule->common.module_api_version);
446f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        result.appendFormat("Camera module name: %s\n",
447f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                mModule->common.name);
448f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        result.appendFormat("Camera module author: %s\n",
449f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                mModule->common.author);
450f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
451f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        write(fd, result.string(), result.size());
45265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (int i = 0; i < mNumberOfCameras; i++) {
453f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            result = String8::format("Camera %d static information:\n", i);
454f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            camera_info info;
455f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala
456f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            status_t rc = mModule->get_camera_info(i, &info);
457f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            if (rc != OK) {
458f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                result.appendFormat("  Error reading static information!\n");
459f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                write(fd, result.string(), result.size());
460f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            } else {
461f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                result.appendFormat("  Facing: %s\n",
462f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                        info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
463f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                result.appendFormat("  Orientation: %d\n", info.orientation);
464f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                int deviceVersion;
465f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                if (mModule->common.module_api_version <
466f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                        CAMERA_MODULE_API_VERSION_2_0) {
467f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                    deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
468f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                } else {
469f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                    deviceVersion = info.device_version;
470f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                }
471f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                result.appendFormat("  Device version: 0x%x\n", deviceVersion);
472f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
473f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                    result.appendFormat("  Device static metadata:\n");
474f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                    write(fd, result.string(), result.size());
475f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                    dump_camera_metadata(info.static_camera_characteristics, fd, 2);
476f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                } else {
477f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                    write(fd, result.string(), result.size());
478f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                }
479f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            }
480f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala
48165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            sp<Client> client = mClient[i].promote();
482f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            if (client == 0) {
483f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                result = String8::format("  Device is closed, no client instance\n");
484f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                write(fd, result.string(), result.size());
485f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                continue;
486f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            }
48765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            hasClient = true;
488f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            result = String8::format("  Device is open. Client instance dump:\n");
489f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            write(fd, result.string(), result.size());
4905e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala            client->dump(fd, args);
49165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
49265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!hasClient) {
493f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            result = String8::format("\nNo active camera clients yet.\n");
494f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            write(fd, result.string(), result.size());
49565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
49665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
49765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (locked) mServiceLock.unlock();
49865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
49965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // change logging level
50065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int n = args.size();
50165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (int i = 0; i + 1 < n; i++) {
502611f61998863d3a3ffae4e5f2b723b7319c59ddfEino-Ville Talvala            String16 verboseOption("-v");
503611f61998863d3a3ffae4e5f2b723b7319c59ddfEino-Ville Talvala            if (args[i] == verboseOption) {
50465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                String8 levelStr(args[i+1]);
50565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                int level = atoi(levelStr.string());
506f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                result = String8::format("\nSetting log level to %d.\n", level);
50765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                setLogLevel(level);
508f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                write(fd, result.string(), result.size());
50965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
51065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
511f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala
51265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
51365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
51465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
51565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
51665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android
517