CameraService.cpp revision ceb388d6c03c38b96dc41c0ea4804b749aa077c4
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
25ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala#include <binder/AppOpsManager.h>
2665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IPCThreadState.h>
2765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IServiceManager.h>
2865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/MemoryBase.h>
2965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/MemoryHeapBase.h>
3065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <cutils/atomic.h>
31b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra#include <cutils/properties.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"
43985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin#include "ProCamera2Client.h"
4465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android {
4665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
4865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Logging support -- this is for debugging only
4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Use "adb shell dumpsys media.camera -v 1" to change it.
505e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvalavolatile int32_t gLogLevel = 0;
5165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
52b8a805261bf0282e992d3608035e47d05a898710Steve Block#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
53b8a805261bf0282e992d3608035e47d05a898710Steve Block#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
5465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic void setLogLevel(int level) {
5665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(level, &gLogLevel);
5765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
5865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
6065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic int getCallingPid() {
6265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return IPCThreadState::self()->getCallingPid();
6365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
6465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic int getCallingUid() {
6665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return IPCThreadState::self()->getCallingUid();
6765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
6865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
7065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// This is ugly and only safe if we never re-create the CameraService, but
7265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// should be ok for now.
7365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic CameraService *gCameraService;
7465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
7565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::CameraService()
76ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    :mSoundRef(0), mModule(0)
7765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
78df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("CameraService started (pid=%d)", getpid());
798951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    gCameraService = this;
808951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev}
8165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
828951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchevvoid CameraService::onFirstRef()
838951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev{
84634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    LOG1("CameraService::onFirstRef");
85634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
868951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    BnCameraService::onFirstRef();
8765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
888951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
898951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev                (const hw_module_t **)&mModule) < 0) {
9029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Could not load camera HAL module");
918951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        mNumberOfCameras = 0;
928951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    }
938951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    else {
94c0dd54f1a77fb94ae69cc3ac5944d718bb6caa28Alex Ray        ALOGI("Loaded \"%s\" camera module", mModule->common.name);
958951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        mNumberOfCameras = mModule->get_number_of_cameras();
968951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        if (mNumberOfCameras > MAX_CAMERAS) {
9729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
988951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev                    mNumberOfCameras, MAX_CAMERAS);
998951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev            mNumberOfCameras = MAX_CAMERAS;
1008951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        }
1018951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        for (int i = 0; i < mNumberOfCameras; i++) {
1028951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev            setCameraFree(i);
1038951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        }
10465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
10565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
10665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
10765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::~CameraService() {
10865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < mNumberOfCameras; i++) {
10965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mBusy[i]) {
11029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("camera %d is still in use in destructor!", i);
11165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
11265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
11365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
11465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    gCameraService = NULL;
11565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
11665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
11765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianint32_t CameraService::getNumberOfCameras() {
11865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mNumberOfCameras;
11965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
12065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
12165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::getCameraInfo(int cameraId,
12265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                                      struct CameraInfo* cameraInfo) {
1238951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    if (!mModule) {
1248951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        return NO_INIT;
1258951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    }
1268951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
12765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
12865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return BAD_VALUE;
12965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
13065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1318951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    struct camera_info info;
1328951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    status_t rc = mModule->get_camera_info(cameraId, &info);
1338951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    cameraInfo->facing = info.facing;
1348951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    cameraInfo->orientation = info.orientation;
1358951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    return rc;
13665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
13765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
138634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinint CameraService::getDeviceVersion(int cameraId, int* facing) {
139634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    struct camera_info info;
140634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (mModule->get_camera_info(cameraId, &info) != OK) {
141634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        return -1;
142634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
143634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
144634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    int deviceVersion;
145634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (mModule->common.module_api_version >= CAMERA_MODULE_API_VERSION_2_0) {
146634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        deviceVersion = info.device_version;
147634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    } else {
148634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
149634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
150634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
151634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (facing) {
152634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        *facing = info.facing;
153634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
154634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
155634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return deviceVersion;
156634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
157634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
15865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<ICamera> CameraService::connect(
159ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const sp<ICameraClient>& cameraClient,
160ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int cameraId,
161ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const String16& clientPackageName,
162ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int clientUid) {
163ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
164ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    String8 clientName8(clientPackageName);
16565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
1665861a9a98c641261c4807c976c750e4611b3a57dTyler Luu
167ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    LOG1("CameraService::connect E (pid %d \"%s\", id %d)", callingPid,
168ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            clientName8.string(), cameraId);
169ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
170ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (clientUid == USE_CALLING_UID) {
171ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        clientUid = getCallingUid();
172ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    } else {
173ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        // We only trust our own process to forward client UIDs
174ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        if (callingPid != getpid()) {
175ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            ALOGE("CameraService::connect X (pid %d) rejected (don't trust clientUid)",
176ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                    callingPid);
177ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            return NULL;
178ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        }
179ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
18065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1818951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    if (!mModule) {
18229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Camera HAL module not loaded");
1838951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        return NULL;
1848951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    }
1858951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
18665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<Client> client;
18765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
18829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
18965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            callingPid, cameraId);
19065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NULL;
19165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
19265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
193a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    char value[PROPERTY_VALUE_MAX];
194a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    property_get("sys.secpolicy.camera.disabled", value, "0");
195a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    if (strcmp(value, "1") == 0) {
196a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li        // Camera is disabled by DevicePolicyManager.
197df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
198a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li        return NULL;
199a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    }
200a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li
20165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mServiceLock);
20208ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li    if (mClient[cameraId] != 0) {
20308ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        client = mClient[cameraId].promote();
20408ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        if (client != 0) {
20508ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li            if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
20608ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                LOG1("CameraService::connect X (pid %d) (the same client)",
20708ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                     callingPid);
20808ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                return client;
20908ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li            } else {
2101d88023e1de6b9f370eb4be944dd9c4480d01f11Igor Murashkin                // TODOSC: need to support 1 regular client, multiple shared clients here
21108ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                ALOGW("CameraService::connect X (pid %d) rejected (existing client).",
21208ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li                      callingPid);
2132fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li                return NULL;
2142fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li            }
2152fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li        }
21608ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        mClient[cameraId].clear();
21708ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li    }
21808ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li
219634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    /*
220634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mBusy is set to false as the last step of the Client destructor,
221634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    after which it is guaranteed that the Client destructor has finished (
222634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    including any inherited destructors)
223634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
224634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    We only need this for a Client subclasses since we don't allow
225634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    multiple Clents to be opened concurrently, but multiple BasicClient
226634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    would be fine
227634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    */
22808ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li    if (mBusy[cameraId]) {
229ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
230ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        ALOGW("CameraService::connect X (pid %d, \"%s\") rejected"
231ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                " (camera %d is still busy).", callingPid,
232ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                clientName8.string(), cameraId);
23308ad5efcef90e24db2863c0f85972ed05fe848a2Wu-cheng Li        return NULL;
23465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
23565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
236634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    int facing = -1;
237634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    int deviceVersion = getDeviceVersion(cameraId, &facing);
238634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
239634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    switch(deviceVersion) {
240634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin      case CAMERA_DEVICE_API_VERSION_1_0:
241ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        client = new CameraClient(this, cameraClient,
242ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                clientPackageName, cameraId,
243ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                facing, callingPid, clientUid, getpid());
244634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        break;
245634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin      case CAMERA_DEVICE_API_VERSION_2_0:
246634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin      case CAMERA_DEVICE_API_VERSION_2_1:
247ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        client = new Camera2Client(this, cameraClient,
248ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                clientPackageName, cameraId,
249ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                facing, callingPid, clientUid, getpid());
250634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        break;
251634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin      case -1:
25229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid camera id %d", cameraId);
253b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li        return NULL;
254634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin      default:
255634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        ALOGE("Unknown camera device HAL version: %d", deviceVersion);
256634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        return NULL;
257b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li    }
2588951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
259634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (client->initialize(mModule) != OK) {
260634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        return NULL;
261634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
262634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
263634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    cameraClient->asBinder()->linkToDeath(this);
264634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
265634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mClient[cameraId] = client;
266634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId, getpid());
267634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return client;
268634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
269634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
270634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinsp<IProCameraUser> CameraService::connect(
271634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin                                        const sp<IProCameraCallbacks>& cameraCb,
272634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin                                        int cameraId)
273634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
274634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    int callingPid = getCallingPid();
275634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
276634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    LOG1("CameraService::connectPro E (pid %d, id %d)", callingPid, cameraId);
277634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
278634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (!mModule) {
279634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        ALOGE("Camera HAL module not loaded");
280634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        return NULL;
281634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
282634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
283634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp<ProClient> client;
284634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
285634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        ALOGE("CameraService::connectPro X (pid %d) rejected (invalid cameraId %d).",
286634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin            callingPid, cameraId);
287634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        return NULL;
28861ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala    }
28961ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala
290634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    char value[PROPERTY_VALUE_MAX];
291634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    property_get("sys.secpolicy.camera.disabled", value, "0");
292634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    if (strcmp(value, "1") == 0) {
293634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        // Camera is disabled by DevicePolicyManager.
294634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
295634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        return NULL;
296634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
297634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
298634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    int facing = -1;
299634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    int deviceVersion = getDeviceVersion(cameraId, &facing);
300634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
30161ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala    switch(deviceVersion) {
302f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala      case CAMERA_DEVICE_API_VERSION_1_0:
303634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        ALOGE("Camera id %d uses HALv1, doesn't support ProCamera", cameraId);
304634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        return NULL;
30561ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        break;
306f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala      case CAMERA_DEVICE_API_VERSION_2_0:
307985fd30a10f6fec4293f071fd258c4726cff5a3dIgor Murashkin      case CAMERA_DEVICE_API_VERSION_2_1:
308ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        client = new ProCamera2Client(this, cameraCb, String16(),
309ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                cameraId, facing, callingPid, USE_CALLING_UID, getpid());
31061ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        break;
311634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin      case -1:
312634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        ALOGE("Invalid camera id %d", cameraId);
313634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        return NULL;
314f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala      default:
31561ab9f93315ea817cd1ac110e2a95da4dab6b4d1Eino-Ville Talvala        ALOGE("Unknown camera device HAL version: %d", deviceVersion);
3165861a9a98c641261c4807c976c750e4611b3a57dTyler Luu        return NULL;
3175861a9a98c641261c4807c976c750e4611b3a57dTyler Luu    }
3185861a9a98c641261c4807c976c750e4611b3a57dTyler Luu
319f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala    if (client->initialize(mModule) != OK) {
320f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala        return NULL;
321f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala    }
322f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala
323634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mProClientList[cameraId].push(client);
324634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
325634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    cameraCb->asBinder()->linkToDeath(this);
326ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
327ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    LOG1("CameraService::connectPro X (id %d, this pid is %d)", cameraId,
328ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            getpid());
32965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return client;
330634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
331634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
332634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return NULL;
33365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
33465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
335634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinvoid CameraService::removeClientByRemote(const wp<IBinder>& remoteBinder) {
33665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
337634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    LOG1("CameraService::removeClientByRemote E (pid %d)", callingPid);
33865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
339ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    // Declare this before the lock to make absolutely sure the
340ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    // destructor won't be called with the lock held.
341ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    Mutex::Autolock lock(mServiceLock);
342ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
343ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    int outIndex;
344634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp<Client> client = findClientUnsafe(remoteBinder, outIndex);
345ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
346ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    if (client != 0) {
347ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        // Found our camera, clear and leave.
348ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        LOG1("removeClient: clear camera %d", outIndex);
349ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        mClient[outIndex].clear();
35065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
351ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        client->unlinkToDeath(this);
352634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    } else {
353634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
354634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        sp<ProClient> clientPro = findProClientUnsafe(remoteBinder);
355634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
356634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        if (clientPro != NULL) {
357634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin            // Found our camera, clear and leave.
358634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin            LOG1("removeClient: clear pro %p", clientPro.get());
359634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
360634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin            clientPro->getRemoteCallback()->asBinder()->unlinkToDeath(this);
361634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        }
362634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    }
363634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
364634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    LOG1("CameraService::removeClientByRemote X (pid %d)", callingPid);
365634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
366634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
367634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinsp<CameraService::ProClient> CameraService::findProClientUnsafe(
368634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin                        const wp<IBinder>& cameraCallbacksRemote)
369634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
370634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp<ProClient> clientPro;
371634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
372634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    for (int i = 0; i < mNumberOfCameras; ++i) {
373634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        Vector<size_t> removeIdx;
374634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
375634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        for (size_t j = 0; j < mProClientList[i].size(); ++j) {
376634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin            wp<ProClient> cl = mProClientList[i][j];
377634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
378634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin            sp<ProClient> clStrong = cl.promote();
379634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin            if (clStrong != NULL && clStrong->getRemote() == cameraCallbacksRemote) {
380634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin                clientPro = clStrong;
381634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin                break;
382634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin            } else if (clStrong == NULL) {
383634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin                // mark to clean up dead ptr
384634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin                removeIdx.push(j);
385634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin            }
386634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        }
387634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
388634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        // remove stale ptrs (in reverse so the indices dont change)
389634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        for (ssize_t j = (ssize_t)removeIdx.size() - 1; j >= 0; --j) {
390634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin            mProClientList[i].removeAt(removeIdx[j]);
391634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        }
392634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
393ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    }
394ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
395634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return clientPro;
396ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin}
397ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
398ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkinsp<CameraService::Client> CameraService::findClientUnsafe(
399294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin                        const wp<IBinder>& cameraClient, int& outIndex) {
400ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    sp<Client> client;
401ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
402ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    for (int i = 0; i < mNumberOfCameras; i++) {
40365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
40465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // This happens when we have already disconnected (or this is
40565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // just another unused camera).
40665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mClient[i] == 0) continue;
40765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
40865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Promote mClient. It can fail if we are called from this path:
409634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        // Client::~Client() -> disconnect() -> removeClientByRemote().
41065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        client = mClient[i].promote();
41165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
412ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        // Clean up stale client entry
413ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        if (client == NULL) {
41465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mClient[i].clear();
41565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            continue;
41665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
41765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
418294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin        if (cameraClient == client->getCameraClient()->asBinder()) {
419ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin            // Found our camera
420ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin            outIndex = i;
421ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin            return client;
42265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
42365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
42465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
425ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    outIndex = -1;
426ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    return NULL;
42765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
42865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
429d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkCameraService::Client* CameraService::getClientByIdUnsafe(int cameraId) {
43065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
431d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    return mClient[cameraId].unsafe_get();
432d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park}
433d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park
434d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkMutex* CameraService::getClientLockById(int cameraId) {
435d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
436d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    return &mClientLock[cameraId];
43765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
43865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
439634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinsp<CameraService::BasicClient> CameraService::getClientByRemote(
440294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin                                const wp<IBinder>& cameraClient) {
441ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
442ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    // Declare this before the lock to make absolutely sure the
443ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    // destructor won't be called with the lock held.
444634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp<BasicClient> client;
445ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
446ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    Mutex::Autolock lock(mServiceLock);
447ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
448ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    int outIndex;
449ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    client = findClientUnsafe(cameraClient, outIndex);
450ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
451ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    return client;
452ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin}
453ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
45465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::onTransact(
45565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
45665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Permission checks
45765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (code) {
45865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case BnCameraService::CONNECT:
459634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        case BnCameraService::CONNECT_PRO:
46065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            const int pid = getCallingPid();
46165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            const int self_pid = getpid();
46265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (pid != self_pid) {
46365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // we're called from a different process, do the real check
46465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (!checkCallingPermission(
46565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        String16("android.permission.CAMERA"))) {
46665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    const int uid = getCallingUid();
46729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Permission Denial: "
46865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                         "can't use the camera pid=%d, uid=%d", pid, uid);
46965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    return PERMISSION_DENIED;
47065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
47165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
47265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
47365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
47465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
47565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BnCameraService::onTransact(code, data, reply, flags);
47665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
47765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
47865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// The reason we need this busy bit is a new CameraService::connect() request
47965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// may come in while the previous Client's destructor has not been run or is
48065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// still running. If the last strong reference of the previous Client is gone
48165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// but the destructor has not been finished, we should not allow the new Client
48265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// to be created because we need to wait for the previous Client to tear down
48365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// the hardware first.
48465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::setCameraBusy(int cameraId) {
48565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(1, &mBusy[cameraId]);
486ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
487ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    ALOGV("setCameraBusy cameraId=%d", cameraId);
48865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
48965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
49065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::setCameraFree(int cameraId) {
49165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(0, &mBusy[cameraId]);
492ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
493ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    ALOGV("setCameraFree cameraId=%d", cameraId);
49465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
49565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
49665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// We share the media players for shutter and recording sound for all clients.
49765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// A reference count is kept to determine when we will actually release the
49865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// media players.
49965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
500ff4f55c8d77e276dbcceedb4e560ca1d91ba38baChih-Chung ChangMediaPlayer* CameraService::newMediaPlayer(const char *file) {
50165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    MediaPlayer* mp = new MediaPlayer();
50265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mp->setDataSource(file, NULL) == NO_ERROR) {
50360a78ac9535878984b0777788760b9ee7465c5e6Eino-Ville Talvala        mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
50465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mp->prepare();
50565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
50629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to load CameraService sounds: %s", file);
50765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NULL;
50865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
50965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mp;
51065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
51165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
51265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::loadSound() {
51365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
51465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::loadSound ref=%d", mSoundRef);
51565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mSoundRef++) return;
51665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
51765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
51865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
51965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
52065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
52165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::releaseSound() {
52265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
52365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
52465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (--mSoundRef) return;
52565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
52665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < NUM_SOUNDS; i++) {
52765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mSoundPlayer[i] != 0) {
52865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSoundPlayer[i]->disconnect();
52965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSoundPlayer[i].clear();
53065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
53165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
53265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
53365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
53465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::playSound(sound_kind kind) {
53565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("playSound(%d)", kind);
53665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
53765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<MediaPlayer> player = mSoundPlayer[kind];
53865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (player != 0) {
5398888a75f01d904541e409e858d23e4150ace34b6Chih-Chung Chang        player->seekTo(0);
5408888a75f01d904541e409e858d23e4150ace34b6Chih-Chung Chang        player->start();
54165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
54265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
54365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
54465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
54565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
54665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::Client(const sp<CameraService>& cameraService,
547b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li        const sp<ICameraClient>& cameraClient,
548ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const String16& clientPackageName,
549ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int cameraId, int cameraFacing,
550ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int clientPid, uid_t clientUid,
551ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int servicePid) :
552634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin        CameraService::BasicClient(cameraService, cameraClient->asBinder(),
553ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                clientPackageName,
554ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                cameraId, cameraFacing,
555ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                clientPid, clientUid,
556ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                servicePid)
557634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
55865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
5592fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li    LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
56065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
56165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraClient = cameraClient;
5625e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala
56365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cameraService->setCameraBusy(cameraId);
56465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cameraService->loadSound();
565ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
5662fd2440d0175ca3e196b01b7541a9e0d4ed9a694Wu-cheng Li    LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
56765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
56865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
56965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// tear down the client
57065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::~Client() {
571634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mDestructionStarted = true;
572634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
573f69c70ded4316ea3ee504ac779bd024433ed4ef7Eino-Ville Talvala    mCameraService->releaseSound();
574ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    finishCameraOps();
575036bc3e2cfc5a11c3f7ace41088c8936dae2e946Igor Murashkin    // unconditionally disconnect. function is idempotent
576036bc3e2cfc5a11c3f7ace41088c8936dae2e946Igor Murashkin    Client::disconnect();
57765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
57865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
579634a51509ee50475f3e9f8ccf897e90fc72ded31Igor MurashkinCameraService::BasicClient::BasicClient(const sp<CameraService>& cameraService,
580ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const sp<IBinder>& remoteCallback,
581ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const String16& clientPackageName,
582ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int cameraId, int cameraFacing,
583ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int clientPid, uid_t clientUid,
584ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int servicePid):
585ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        mClientPackageName(clientPackageName)
586634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
587634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mCameraService = cameraService;
588634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mRemoteCallback = remoteCallback;
589634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mCameraId = cameraId;
590634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mCameraFacing = cameraFacing;
591634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mClientPid = clientPid;
592ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mClientUid = clientUid;
593634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mServicePid = servicePid;
594ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mOpsActive = false;
595634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mDestructionStarted = false;
596634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
597634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
598634a51509ee50475f3e9f8ccf897e90fc72ded31Igor MurashkinCameraService::BasicClient::~BasicClient() {
599634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mDestructionStarted = true;
600634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
601634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
602634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinvoid CameraService::BasicClient::disconnect() {
603634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mCameraService->removeClientByRemote(mRemoteCallback);
604634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
605634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
606ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvalastatus_t CameraService::BasicClient::startCameraOps() {
607ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    int32_t res;
608ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
609ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mOpsCallback = new OpsCallback(this);
610ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
611ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
612ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            mClientPackageName, mOpsCallback);
613ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    res = mAppOpsManager.startOp(AppOpsManager::OP_CAMERA,
614ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            mClientUid, mClientPackageName);
615ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
616ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (res != AppOpsManager::MODE_ALLOWED) {
617ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        ALOGI("Camera %d: Access for \"%s\" has been revoked",
618ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                mCameraId, String8(mClientPackageName).string());
619ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        return PERMISSION_DENIED;
620ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
621ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mOpsActive = true;
622ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    return OK;
623ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
624ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
625ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvalastatus_t CameraService::BasicClient::finishCameraOps() {
626ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (mOpsActive) {
627ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
628ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                mClientPackageName);
629ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        mOpsActive = false;
630ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
631ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mAppOpsManager.stopWatchingMode(mOpsCallback);
632ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mOpsCallback.clear();
633ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
634ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    return OK;
635ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
636ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
637ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvalavoid CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
638ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    String8 name(packageName);
639ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    String8 myName(mClientPackageName);
640ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
641ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (op != AppOpsManager::OP_CAMERA) {
642ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        ALOGW("Unexpected app ops notification received: %d", op);
643ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        return;
644ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
645ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
646ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    int32_t res;
647ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
648ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            mClientUid, mClientPackageName);
649ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    ALOGV("checkOp returns: %d, %s ", res,
650ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
651ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            res == AppOpsManager::MODE_IGNORED ? "IGNORED" :
652ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            res == AppOpsManager::MODE_ERRORED ? "ERRORED" :
653ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala            "UNKNOWN");
654ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
655ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (res != AppOpsManager::MODE_ALLOWED) {
656ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        ALOGI("Camera %d: Access for \"%s\" revoked", mCameraId,
657ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                myName.string());
658ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        // Reset the client PID to allow server-initiated disconnect,
659ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        // and to prevent further calls by client.
660ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        mClientPid = getCallingPid();
661ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        notifyError();
662ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        disconnect();
663ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
664ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
665ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
66665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
66765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
668d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkMutex* CameraService::Client::getClientLockFromCookie(void* user) {
669d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    return gCameraService->getClientLockById((int) user);
670d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park}
671d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park
672d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
673d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park// be acquired for this to be safe
674d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young ParkCameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
675d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    Client* client = gCameraService->getClientByIdUnsafe((int) user);
67665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
67765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // This could happen if the Client is in the process of shutting down (the
67865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // last strong reference is gone, but the destructor hasn't finished
67965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // stopping the hardware).
680d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    if (client == NULL) return NULL;
681d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park
682d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    // destruction already started, so should not be accessed
683d8973a71a3d1dd670e5dcdf6e94ec0cd45444eecKeun young Park    if (client->mDestructionStarted) return NULL;
68465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
68565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return client;
68665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
68765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
688ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvalavoid CameraService::Client::notifyError() {
689ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    mCameraClient->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
690ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
691ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
692036bc3e2cfc5a11c3f7ace41088c8936dae2e946Igor Murashkin// NOTE: function is idempotent
6935e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvalavoid CameraService::Client::disconnect() {
694634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    BasicClient::disconnect();
6955e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala    mCameraService->setCameraFree(mCameraId);
696e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li}
697e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li
698ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville TalvalaCameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
699ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        mClient(client) {
700ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
701ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
702ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvalavoid CameraService::Client::OpsCallback::opChanged(int32_t op,
703ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const String16& packageName) {
704ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    sp<BasicClient> client = mClient.promote();
705ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    if (client != NULL) {
706ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        client->opChanged(op, packageName);
707ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    }
708ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
709ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
71065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
711634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin//                  IProCamera
712634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin// ----------------------------------------------------------------------------
713634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
714634a51509ee50475f3e9f8ccf897e90fc72ded31Igor MurashkinCameraService::ProClient::ProClient(const sp<CameraService>& cameraService,
715ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const sp<IProCameraCallbacks>& remoteCallback,
716ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        const String16& clientPackageName,
717ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int cameraId,
718ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int cameraFacing,
719ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int clientPid,
720ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        uid_t clientUid,
721ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        int servicePid)
722ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala        : CameraService::BasicClient(cameraService, remoteCallback->asBinder(),
723ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                clientPackageName, cameraId, cameraFacing,
724ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala                clientPid,  clientUid, servicePid)
725634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
726634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mRemoteCallback = remoteCallback;
727634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
728634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
729634a51509ee50475f3e9f8ccf897e90fc72ded31Igor MurashkinCameraService::ProClient::~ProClient() {
730634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    mDestructionStarted = true;
731634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
732634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    ProClient::disconnect();
733634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
734634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
735634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinstatus_t CameraService::ProClient::connect(const sp<IProCameraCallbacks>& callbacks) {
736634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    ALOGE("%s: not implemented yet", __FUNCTION__);
737634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
738634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return INVALID_OPERATION;
739634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
740634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
741634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinvoid CameraService::ProClient::disconnect() {
742634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    BasicClient::disconnect();
743634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
744634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
745634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinstatus_t CameraService::ProClient::initialize(camera_module_t* module)
746634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin{
747634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    ALOGW("%s: not implemented yet", __FUNCTION__);
748634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return OK;
749634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
750634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
751634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinstatus_t CameraService::ProClient::exclusiveTryLock() {
752634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    ALOGE("%s: not implemented yet", __FUNCTION__);
753634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return INVALID_OPERATION;
754634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
755634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
756634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinstatus_t CameraService::ProClient::exclusiveLock() {
757634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    ALOGE("%s: not implemented yet", __FUNCTION__);
758634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return INVALID_OPERATION;
759634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
760634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
761634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinstatus_t CameraService::ProClient::exclusiveUnlock() {
762634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    ALOGE("%s: not implemented yet", __FUNCTION__);
763634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return INVALID_OPERATION;
764634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
765634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
766634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinbool CameraService::ProClient::hasExclusiveLock() {
767634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    ALOGE("%s: not implemented yet", __FUNCTION__);
768634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return false;
769634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
770634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
771634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinstatus_t CameraService::ProClient::submitRequest(camera_metadata_t* request, bool streaming) {
772634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    ALOGE("%s: not implemented yet", __FUNCTION__);
773634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
774634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    free_camera_metadata(request);
775634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
776634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return INVALID_OPERATION;
777634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
778634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
779634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinstatus_t CameraService::ProClient::cancelRequest(int requestId) {
780634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    ALOGE("%s: not implemented yet", __FUNCTION__);
781634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
782634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return INVALID_OPERATION;
783634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
784634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
785634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinstatus_t CameraService::ProClient::requestStream(int streamId) {
786634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    ALOGE("%s: not implemented yet", __FUNCTION__);
787634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
788634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return INVALID_OPERATION;
789634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
790634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
791634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkinstatus_t CameraService::ProClient::cancelStream(int streamId) {
792634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    ALOGE("%s: not implemented yet", __FUNCTION__);
793634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
794634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    return INVALID_OPERATION;
795634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin}
796634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin
797ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvalavoid CameraService::ProClient::notifyError() {
798ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala    ALOGE("%s: not implemented yet", __FUNCTION__);
799ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala}
800ceb388d6c03c38b96dc41c0ea4804b749aa077c4Eino-Ville Talvala
801634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin// ----------------------------------------------------------------------------
80265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
80365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50;
80465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockSleep = 60000;
80565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
80665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic bool tryLock(Mutex& mutex)
80765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
80865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = false;
80965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < kDumpLockRetries; ++i) {
81065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mutex.tryLock() == NO_ERROR) {
81165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            locked = true;
81265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
81365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
81465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        usleep(kDumpLockSleep);
81565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
81665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return locked;
81765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
81865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
81965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::dump(int fd, const Vector<String16>& args) {
82065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
82165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
822611f61998863d3a3ffae4e5f2b723b7319c59ddfEino-Ville Talvala        result.appendFormat("Permission Denial: "
82365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                "can't dump CameraService from pid=%d, uid=%d\n",
82465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                getCallingPid(),
82565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                getCallingUid());
82665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        write(fd, result.string(), result.size());
82765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
82865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool locked = tryLock(mServiceLock);
82965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // failed to lock - CameraService is probably deadlocked
83065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!locked) {
831611f61998863d3a3ffae4e5f2b723b7319c59ddfEino-Ville Talvala            result.append("CameraService may be deadlocked\n");
832f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            write(fd, result.string(), result.size());
83365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
83465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
83565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool hasClient = false;
836f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        if (!mModule) {
837f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            result = String8::format("No camera module available!\n");
838f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            write(fd, result.string(), result.size());
839f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            return NO_ERROR;
840f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        }
841f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala
842f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        result = String8::format("Camera module HAL API version: 0x%x\n",
843f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                mModule->common.hal_api_version);
844f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        result.appendFormat("Camera module API version: 0x%x\n",
845f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                mModule->common.module_api_version);
846f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        result.appendFormat("Camera module name: %s\n",
847f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                mModule->common.name);
848f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        result.appendFormat("Camera module author: %s\n",
849f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                mModule->common.author);
850f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
851f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala        write(fd, result.string(), result.size());
85265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (int i = 0; i < mNumberOfCameras; i++) {
853f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            result = String8::format("Camera %d static information:\n", i);
854f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            camera_info info;
855f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala
856f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            status_t rc = mModule->get_camera_info(i, &info);
857f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            if (rc != OK) {
858f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                result.appendFormat("  Error reading static information!\n");
859f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                write(fd, result.string(), result.size());
860f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            } else {
861f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                result.appendFormat("  Facing: %s\n",
862f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                        info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
863f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                result.appendFormat("  Orientation: %d\n", info.orientation);
864f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                int deviceVersion;
865f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                if (mModule->common.module_api_version <
866f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                        CAMERA_MODULE_API_VERSION_2_0) {
867f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                    deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
868f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                } else {
869f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                    deviceVersion = info.device_version;
870f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                }
871f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                result.appendFormat("  Device version: 0x%x\n", deviceVersion);
872f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
873f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                    result.appendFormat("  Device static metadata:\n");
874f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                    write(fd, result.string(), result.size());
875428b77a2b94b74665a47375b3fdb893b98d71269Eino-Ville Talvala                    dump_indented_camera_metadata(info.static_camera_characteristics,
876428b77a2b94b74665a47375b3fdb893b98d71269Eino-Ville Talvala                            fd, 2, 4);
877f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                } else {
878f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                    write(fd, result.string(), result.size());
879f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                }
880f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            }
881f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala
88265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            sp<Client> client = mClient[i].promote();
883f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            if (client == 0) {
884f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                result = String8::format("  Device is closed, no client instance\n");
885f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                write(fd, result.string(), result.size());
886f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                continue;
887f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            }
88865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            hasClient = true;
889f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            result = String8::format("  Device is open. Client instance dump:\n");
890f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            write(fd, result.string(), result.size());
8915e08d60617fc63c2e41f9069ff89f5c00db2617dEino-Ville Talvala            client->dump(fd, args);
89265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
89365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!hasClient) {
894f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            result = String8::format("\nNo active camera clients yet.\n");
895f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala            write(fd, result.string(), result.size());
89665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
89765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
89865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (locked) mServiceLock.unlock();
89965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
90065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // change logging level
90165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int n = args.size();
90265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (int i = 0; i + 1 < n; i++) {
903611f61998863d3a3ffae4e5f2b723b7319c59ddfEino-Ville Talvala            String16 verboseOption("-v");
904611f61998863d3a3ffae4e5f2b723b7319c59ddfEino-Ville Talvala            if (args[i] == verboseOption) {
90565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                String8 levelStr(args[i+1]);
90665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                int level = atoi(levelStr.string());
907f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                result = String8::format("\nSetting log level to %d.\n", level);
90865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                setLogLevel(level);
909f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala                write(fd, result.string(), result.size());
91065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
91165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
912f5926136ad328e95a79336b051d6f853443eaab9Eino-Ville Talvala
91365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
91465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
91565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
91665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
917ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin/*virtual*/void CameraService::binderDied(
918ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    const wp<IBinder> &who) {
919ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
920294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin    /**
921294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin      * While tempting to promote the wp<IBinder> into a sp,
922294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin      * it's actually not supported by the binder driver
923294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin      */
924294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin
925ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    ALOGV("java clients' binder died");
926ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
927634a51509ee50475f3e9f8ccf897e90fc72ded31Igor Murashkin    sp<BasicClient> cameraClient = getClientByRemote(who);
928ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
929294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41Igor Murashkin    if (cameraClient == 0) {
930ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        ALOGV("java clients' binder death already cleaned up (normal case)");
931ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin        return;
932ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    }
933ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
934ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    ALOGW("Disconnecting camera client %p since the binder for it "
935ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin          "died (this pid %d)", cameraClient.get(), getCallingPid());
936ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
937ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin    cameraClient->disconnect();
938ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
939ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin}
940ecf17e82505fdb60d59e00b6dd59036df93de655Igor Murashkin
94165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android
942