CameraService.cpp revision 294d0eca9eabfaa3ef0ee8bee7ccf3eaaa925e41
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Copyright (C) 2008, The Android Open Source Project
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** you may not use this file except in compliance with the License.
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** You may obtain a copy of the License at
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project**
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14392744175c4de67dc98e72da6745e6351118c985San Mehat** See the License for the specific language governing permissions and
15392744175c4de67dc98e72da6745e6351118c985San Mehat** limitations under the License.
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LOG_TAG "CameraService"
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project//#define LOG_NDEBUG 0
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/types.h>
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <pthread.h>
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <binder/IPCThreadState.h>
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <binder/IServiceManager.h>
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <binder/MemoryBase.h>
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <binder/MemoryHeapBase.h>
29392744175c4de67dc98e72da6745e6351118c985San Mehat#include <cutils/atomic.h>
308b37c91b934bf22d8ae52bebad7f1f22f16d1132Dmitry Shmidt#include <cutils/properties.h>
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <gui/SurfaceTextureClient.h>
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <gui/Surface.h>
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <hardware/hardware.h>
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <media/AudioSystem.h>
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <media/mediaplayer.h>
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <utils/Errors.h>
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <utils/Log.h>
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <utils/String16.h>
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "CameraService.h"
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "CameraClient.h"
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "Camera2Client.h"
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnamespace android {
458b37c91b934bf22d8ae52bebad7f1f22f16d1132Dmitry Shmidt
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// Logging support -- this is for debugging only
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// Use "adb shell dumpsys media.camera -v 1" to change it.
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvolatile int32_t gLogLevel = 0;
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LOG2(...) ALOGD_IF(gLogLevel >= 2, __VA_ARGS__);
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void setLogLevel(int level) {
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    android_atomic_write(level, &gLogLevel);
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int getCallingPid() {
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return IPCThreadState::self()->getCallingPid();
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int getCallingUid() {
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return IPCThreadState::self()->getCallingUid();
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// ----------------------------------------------------------------------------
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// This is ugly and only safe if we never re-create the CameraService, but
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// should be ok for now.
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic CameraService *gCameraService;
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectCameraService::CameraService()
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project:mSoundRef(0), mModule(0)
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ALOGI("CameraService started (pid=%d)", getpid());
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    gCameraService = this;
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid CameraService::onFirstRef()
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BnCameraService::onFirstRef();
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (hw_get_module(CAMERA_HARDWARE_MODULE_ID,
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                (const hw_module_t **)&mModule) < 0) {
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ALOGE("Could not load camera HAL module");
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mNumberOfCameras = 0;
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    else {
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mNumberOfCameras = mModule->get_number_of_cameras();
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (mNumberOfCameras > MAX_CAMERAS) {
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ALOGE("Number of cameras(%d) > MAX_CAMERAS(%d).",
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    mNumberOfCameras, MAX_CAMERAS);
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            mNumberOfCameras = MAX_CAMERAS;
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for (int i = 0; i < mNumberOfCameras; i++) {
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            setCameraFree(i);
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectCameraService::~CameraService() {
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (int i = 0; i < mNumberOfCameras; i++) {
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (mBusy[i]) {
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ALOGE("camera %d is still in use in destructor!", i);
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    gCameraService = NULL;
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint32_t CameraService::getNumberOfCameras() {
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return mNumberOfCameras;
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatus_t CameraService::getCameraInfo(int cameraId,
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                      struct CameraInfo* cameraInfo) {
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!mModule) {
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return NO_INIT;
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return BAD_VALUE;
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1268b37c91b934bf22d8ae52bebad7f1f22f16d1132Dmitry Shmidt
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct camera_info info;
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    status_t rc = mModule->get_camera_info(cameraId, &info);
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    cameraInfo->facing = info.facing;
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    cameraInfo->orientation = info.orientation;
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return rc;
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsp<ICamera> CameraService::connect(
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        const sp<ICameraClient>& cameraClient, int cameraId) {
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int callingPid = getCallingPid();
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId);
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!mModule) {
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ALOGE("Camera HAL module not loaded");
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return NULL;
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
145392744175c4de67dc98e72da6745e6351118c985San Mehat    sp<Client> client;
1468b37c91b934bf22d8ae52bebad7f1f22f16d1132Dmitry Shmidt    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
1478b37c91b934bf22d8ae52bebad7f1f22f16d1132Dmitry Shmidt        ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
1488b37c91b934bf22d8ae52bebad7f1f22f16d1132Dmitry Shmidt            callingPid, cameraId);
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return NULL;
150392744175c4de67dc98e72da6745e6351118c985San Mehat    }
151392744175c4de67dc98e72da6745e6351118c985San Mehat
152392744175c4de67dc98e72da6745e6351118c985San Mehat    char value[PROPERTY_VALUE_MAX];
153392744175c4de67dc98e72da6745e6351118c985San Mehat    property_get("sys.secpolicy.camera.disabled", value, "0");
154392744175c4de67dc98e72da6745e6351118c985San Mehat    if (strcmp(value, "1") == 0) {
155392744175c4de67dc98e72da6745e6351118c985San Mehat        // Camera is disabled by DevicePolicyManager.
156392744175c4de67dc98e72da6745e6351118c985San Mehat        ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
157392744175c4de67dc98e72da6745e6351118c985San Mehat        return NULL;
158392744175c4de67dc98e72da6745e6351118c985San Mehat    }
159392744175c4de67dc98e72da6745e6351118c985San Mehat
160392744175c4de67dc98e72da6745e6351118c985San Mehat    Mutex::Autolock lock(mServiceLock);
161392744175c4de67dc98e72da6745e6351118c985San Mehat    if (mClient[cameraId] != 0) {
162392744175c4de67dc98e72da6745e6351118c985San Mehat        client = mClient[cameraId].promote();
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (client != 0) {
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                LOG1("CameraService::connect X (pid %d) (the same client)",
166392744175c4de67dc98e72da6745e6351118c985San Mehat                     callingPid);
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return client;
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ALOGW("CameraService::connect X (pid %d) rejected (existing client).",
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                      callingPid);
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return NULL;
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mClient[cameraId].clear();
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mBusy[cameraId]) {
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ALOGW("CameraService::connect X (pid %d) rejected"
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                " (camera %d is still busy).", callingPid, cameraId);
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return NULL;
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct camera_info info;
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mModule->get_camera_info(cameraId, &info) != OK) {
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ALOGE("Invalid camera id %d", cameraId);
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return NULL;
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int deviceVersion;
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (mModule->common.module_api_version == CAMERA_MODULE_API_VERSION_2_0) {
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        deviceVersion = info.device_version;
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch(deviceVersion) {
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project      case CAMERA_DEVICE_API_VERSION_1_0:
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        client = new CameraClient(this, cameraClient, cameraId,
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                info.facing, callingPid, getpid());
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project      case CAMERA_DEVICE_API_VERSION_2_0:
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        client = new Camera2Client(this, cameraClient, cameraId,
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                info.facing, callingPid, getpid());
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        break;
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project      default:
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ALOGE("Unknown camera device HAL version: %d", deviceVersion);
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return NULL;
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
209392744175c4de67dc98e72da6745e6351118c985San Mehat
210392744175c4de67dc98e72da6745e6351118c985San Mehat    if (client->initialize(mModule) != OK) {
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return NULL;
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
2138b37c91b934bf22d8ae52bebad7f1f22f16d1132Dmitry Shmidt
2148b37c91b934bf22d8ae52bebad7f1f22f16d1132Dmitry Shmidt    cameraClient->asBinder()->linkToDeath(this);
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    mClient[cameraId] = client;
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    LOG1("CameraService::connect X (id %d, this pid is %d)", cameraId, getpid());
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return client;
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid CameraService::removeClient(const sp<ICameraClient>& cameraClient) {
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int callingPid = getCallingPid();
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    LOG1("CameraService::removeClient E (pid %d)", callingPid);
2248b37c91b934bf22d8ae52bebad7f1f22f16d1132Dmitry Shmidt
2258b37c91b934bf22d8ae52bebad7f1f22f16d1132Dmitry Shmidt    // Declare this before the lock to make absolutely sure the
226392744175c4de67dc98e72da6745e6351118c985San Mehat    // destructor won't be called with the lock held.
227392744175c4de67dc98e72da6745e6351118c985San Mehat    Mutex::Autolock lock(mServiceLock);
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int outIndex;
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sp<Client> client = findClientUnsafe(cameraClient->asBinder(), outIndex);
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (client != 0) {
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        // Found our camera, clear and leave.
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        LOG1("removeClient: clear camera %d", outIndex);
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        mClient[outIndex].clear();
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        client->unlinkToDeath(this);
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    LOG1("CameraService::removeClient X (pid %d)", callingPid);
241}
242
243sp<CameraService::Client> CameraService::findClientUnsafe(
244                        const wp<IBinder>& cameraClient, int& outIndex) {
245    sp<Client> client;
246
247    for (int i = 0; i < mNumberOfCameras; i++) {
248
249        // This happens when we have already disconnected (or this is
250        // just another unused camera).
251        if (mClient[i] == 0) continue;
252
253        // Promote mClient. It can fail if we are called from this path:
254        // Client::~Client() -> disconnect() -> removeClient().
255        client = mClient[i].promote();
256
257        // Clean up stale client entry
258        if (client == NULL) {
259            mClient[i].clear();
260            continue;
261        }
262
263        if (cameraClient == client->getCameraClient()->asBinder()) {
264            // Found our camera
265            outIndex = i;
266            return client;
267        }
268    }
269
270    outIndex = -1;
271    return NULL;
272}
273
274CameraService::Client* CameraService::getClientByIdUnsafe(int cameraId) {
275    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
276    return mClient[cameraId].unsafe_get();
277}
278
279Mutex* CameraService::getClientLockById(int cameraId) {
280    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
281    return &mClientLock[cameraId];
282}
283
284sp<CameraService::Client> CameraService::getClientByRemote(
285                                const wp<IBinder>& cameraClient) {
286
287    // Declare this before the lock to make absolutely sure the
288    // destructor won't be called with the lock held.
289    sp<Client> client;
290
291    Mutex::Autolock lock(mServiceLock);
292
293    int outIndex;
294    client = findClientUnsafe(cameraClient, outIndex);
295
296    return client;
297}
298
299status_t CameraService::onTransact(
300    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
301    // Permission checks
302    switch (code) {
303        case BnCameraService::CONNECT:
304            const int pid = getCallingPid();
305            const int self_pid = getpid();
306            if (pid != self_pid) {
307                // we're called from a different process, do the real check
308                if (!checkCallingPermission(
309                        String16("android.permission.CAMERA"))) {
310                    const int uid = getCallingUid();
311                    ALOGE("Permission Denial: "
312                         "can't use the camera pid=%d, uid=%d", pid, uid);
313                    return PERMISSION_DENIED;
314                }
315            }
316            break;
317    }
318
319    return BnCameraService::onTransact(code, data, reply, flags);
320}
321
322// The reason we need this busy bit is a new CameraService::connect() request
323// may come in while the previous Client's destructor has not been run or is
324// still running. If the last strong reference of the previous Client is gone
325// but the destructor has not been finished, we should not allow the new Client
326// to be created because we need to wait for the previous Client to tear down
327// the hardware first.
328void CameraService::setCameraBusy(int cameraId) {
329    android_atomic_write(1, &mBusy[cameraId]);
330
331    ALOGV("setCameraBusy cameraId=%d", cameraId);
332}
333
334void CameraService::setCameraFree(int cameraId) {
335    android_atomic_write(0, &mBusy[cameraId]);
336
337    ALOGV("setCameraFree cameraId=%d", cameraId);
338}
339
340// We share the media players for shutter and recording sound for all clients.
341// A reference count is kept to determine when we will actually release the
342// media players.
343
344MediaPlayer* CameraService::newMediaPlayer(const char *file) {
345    MediaPlayer* mp = new MediaPlayer();
346    if (mp->setDataSource(file, NULL) == NO_ERROR) {
347        mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
348        mp->prepare();
349    } else {
350        ALOGE("Failed to load CameraService sounds: %s", file);
351        return NULL;
352    }
353    return mp;
354}
355
356void CameraService::loadSound() {
357    Mutex::Autolock lock(mSoundLock);
358    LOG1("CameraService::loadSound ref=%d", mSoundRef);
359    if (mSoundRef++) return;
360
361    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
362    mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
363}
364
365void CameraService::releaseSound() {
366    Mutex::Autolock lock(mSoundLock);
367    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
368    if (--mSoundRef) return;
369
370    for (int i = 0; i < NUM_SOUNDS; i++) {
371        if (mSoundPlayer[i] != 0) {
372            mSoundPlayer[i]->disconnect();
373            mSoundPlayer[i].clear();
374        }
375    }
376}
377
378void CameraService::playSound(sound_kind kind) {
379    LOG1("playSound(%d)", kind);
380    Mutex::Autolock lock(mSoundLock);
381    sp<MediaPlayer> player = mSoundPlayer[kind];
382    if (player != 0) {
383        player->seekTo(0);
384        player->start();
385    }
386}
387
388// ----------------------------------------------------------------------------
389
390CameraService::Client::Client(const sp<CameraService>& cameraService,
391        const sp<ICameraClient>& cameraClient,
392        int cameraId, int cameraFacing, int clientPid, int servicePid) {
393    int callingPid = getCallingPid();
394    LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
395
396    mCameraService = cameraService;
397    mCameraClient = cameraClient;
398    mCameraId = cameraId;
399    mCameraFacing = cameraFacing;
400    mClientPid = clientPid;
401    mServicePid = servicePid;
402    mDestructionStarted = false;
403
404    cameraService->setCameraBusy(cameraId);
405    cameraService->loadSound();
406    LOG1("Client::Client X (pid %d, id %d)", callingPid, cameraId);
407}
408
409// tear down the client
410CameraService::Client::~Client() {
411    mCameraService->releaseSound();
412}
413
414// ----------------------------------------------------------------------------
415
416Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
417    return gCameraService->getClientLockById((int) user);
418}
419
420// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
421// be acquired for this to be safe
422CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
423    Client* client = gCameraService->getClientByIdUnsafe((int) user);
424
425    // This could happen if the Client is in the process of shutting down (the
426    // last strong reference is gone, but the destructor hasn't finished
427    // stopping the hardware).
428    if (client == NULL) return NULL;
429
430    // destruction already started, so should not be accessed
431    if (client->mDestructionStarted) return NULL;
432
433    return client;
434}
435
436void CameraService::Client::disconnect() {
437    mCameraService->removeClient(mCameraClient);
438    mCameraService->setCameraFree(mCameraId);
439}
440
441// ----------------------------------------------------------------------------
442
443static const int kDumpLockRetries = 50;
444static const int kDumpLockSleep = 60000;
445
446static bool tryLock(Mutex& mutex)
447{
448    bool locked = false;
449    for (int i = 0; i < kDumpLockRetries; ++i) {
450        if (mutex.tryLock() == NO_ERROR) {
451            locked = true;
452            break;
453        }
454        usleep(kDumpLockSleep);
455    }
456    return locked;
457}
458
459status_t CameraService::dump(int fd, const Vector<String16>& args) {
460    String8 result;
461    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
462        result.appendFormat("Permission Denial: "
463                "can't dump CameraService from pid=%d, uid=%d\n",
464                getCallingPid(),
465                getCallingUid());
466        write(fd, result.string(), result.size());
467    } else {
468        bool locked = tryLock(mServiceLock);
469        // failed to lock - CameraService is probably deadlocked
470        if (!locked) {
471            result.append("CameraService may be deadlocked\n");
472            write(fd, result.string(), result.size());
473        }
474
475        bool hasClient = false;
476        if (!mModule) {
477            result = String8::format("No camera module available!\n");
478            write(fd, result.string(), result.size());
479            return NO_ERROR;
480        }
481
482        result = String8::format("Camera module HAL API version: 0x%x\n",
483                mModule->common.hal_api_version);
484        result.appendFormat("Camera module API version: 0x%x\n",
485                mModule->common.module_api_version);
486        result.appendFormat("Camera module name: %s\n",
487                mModule->common.name);
488        result.appendFormat("Camera module author: %s\n",
489                mModule->common.author);
490        result.appendFormat("Number of camera devices: %d\n\n", mNumberOfCameras);
491        write(fd, result.string(), result.size());
492        for (int i = 0; i < mNumberOfCameras; i++) {
493            result = String8::format("Camera %d static information:\n", i);
494            camera_info info;
495
496            status_t rc = mModule->get_camera_info(i, &info);
497            if (rc != OK) {
498                result.appendFormat("  Error reading static information!\n");
499                write(fd, result.string(), result.size());
500            } else {
501                result.appendFormat("  Facing: %s\n",
502                        info.facing == CAMERA_FACING_BACK ? "BACK" : "FRONT");
503                result.appendFormat("  Orientation: %d\n", info.orientation);
504                int deviceVersion;
505                if (mModule->common.module_api_version <
506                        CAMERA_MODULE_API_VERSION_2_0) {
507                    deviceVersion = CAMERA_DEVICE_API_VERSION_1_0;
508                } else {
509                    deviceVersion = info.device_version;
510                }
511                result.appendFormat("  Device version: 0x%x\n", deviceVersion);
512                if (deviceVersion >= CAMERA_DEVICE_API_VERSION_2_0) {
513                    result.appendFormat("  Device static metadata:\n");
514                    write(fd, result.string(), result.size());
515                    dump_indented_camera_metadata(info.static_camera_characteristics,
516                            fd, 2, 4);
517                } else {
518                    write(fd, result.string(), result.size());
519                }
520            }
521
522            sp<Client> client = mClient[i].promote();
523            if (client == 0) {
524                result = String8::format("  Device is closed, no client instance\n");
525                write(fd, result.string(), result.size());
526                continue;
527            }
528            hasClient = true;
529            result = String8::format("  Device is open. Client instance dump:\n");
530            write(fd, result.string(), result.size());
531            client->dump(fd, args);
532        }
533        if (!hasClient) {
534            result = String8::format("\nNo active camera clients yet.\n");
535            write(fd, result.string(), result.size());
536        }
537
538        if (locked) mServiceLock.unlock();
539
540        // change logging level
541        int n = args.size();
542        for (int i = 0; i + 1 < n; i++) {
543            String16 verboseOption("-v");
544            if (args[i] == verboseOption) {
545                String8 levelStr(args[i+1]);
546                int level = atoi(levelStr.string());
547                result = String8::format("\nSetting log level to %d.\n", level);
548                setLogLevel(level);
549                write(fd, result.string(), result.size());
550            }
551        }
552
553    }
554    return NO_ERROR;
555}
556
557/*virtual*/void CameraService::binderDied(
558    const wp<IBinder> &who) {
559
560    /**
561      * While tempting to promote the wp<IBinder> into a sp,
562      * it's actually not supported by the binder driver
563      */
564
565    ALOGV("java clients' binder died");
566
567    sp<Client> cameraClient = getClientByRemote(who);
568
569    if (cameraClient == 0) {
570        ALOGV("java clients' binder death already cleaned up (normal case)");
571        return;
572    }
573
574    ALOGW("Disconnecting camera client %p since the binder for it "
575          "died (this pid %d)", cameraClient.get(), getCallingPid());
576
577    cameraClient->disconnect();
578
579}
580
581}; // namespace android
582