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