CameraService.cpp revision b5ca4618a722a21f084fe8bfc1c2992749ccd3f0
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" 1965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 2065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <stdio.h> 2165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <sys/types.h> 2265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <pthread.h> 2365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 2465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IPCThreadState.h> 2565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IServiceManager.h> 2665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/MemoryBase.h> 2765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/MemoryHeapBase.h> 2865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <cutils/atomic.h> 29b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra#include <cutils/properties.h> 3065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <hardware/hardware.h> 3165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/AudioSystem.h> 3265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/mediaplayer.h> 3365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <surfaceflinger/ISurface.h> 3465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <ui/Overlay.h> 3565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Errors.h> 3665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Log.h> 3765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/String16.h> 3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 3965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "CameraService.h" 4065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 4165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android { 4265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 4365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 4465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Logging support -- this is for debugging only 4565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Use "adb shell dumpsys media.camera -v 1" to change it. 4665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic volatile int32_t gLogLevel = 0; 4765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 4865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG1(...) LOGD_IF(gLogLevel >= 1, __VA_ARGS__); 4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG2(...) LOGD_IF(gLogLevel >= 2, __VA_ARGS__); 5065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic void setLogLevel(int level) { 5265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian android_atomic_write(level, &gLogLevel); 5365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 5465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 5665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic int getCallingPid() { 5865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return IPCThreadState::self()->getCallingPid(); 5965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 6065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 6165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic int getCallingUid() { 6265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return IPCThreadState::self()->getCallingUid(); 6365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 6465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 6565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 6665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 6765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// This is ugly and only safe if we never re-create the CameraService, but 6865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// should be ok for now. 6965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic CameraService *gCameraService; 7065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 7165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::CameraService() 7265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian:mSoundRef(0) 7365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 7465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGI("CameraService started (pid=%d)", getpid()); 7565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 7665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mNumberOfCameras = HAL_getNumberOfCameras(); 7765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mNumberOfCameras > MAX_CAMERAS) { 7865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("Number of cameras(%d) > MAX_CAMERAS(%d).", 7965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mNumberOfCameras, MAX_CAMERAS); 8065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mNumberOfCameras = MAX_CAMERAS; 8165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 8265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 8365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (int i = 0; i < mNumberOfCameras; i++) { 8465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian setCameraFree(i); 8565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 8665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 8765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian gCameraService = this; 8865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 8965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 9065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::~CameraService() { 9165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (int i = 0; i < mNumberOfCameras; i++) { 9265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mBusy[i]) { 9365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("camera %d is still in use in destructor!", i); 9465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 9565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 9665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 9765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian gCameraService = NULL; 9865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 9965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 10065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianint32_t CameraService::getNumberOfCameras() { 10165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mNumberOfCameras; 10265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 10365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 10465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::getCameraInfo(int cameraId, 10565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian struct CameraInfo* cameraInfo) { 10665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (cameraId < 0 || cameraId >= mNumberOfCameras) { 10765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return BAD_VALUE; 10865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 10965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 11065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian HAL_getCameraInfo(cameraId, cameraInfo); 11165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return OK; 11265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 11365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 11465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<ICamera> CameraService::connect( 11565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const sp<ICameraClient>& cameraClient, int cameraId) { 11665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int callingPid = getCallingPid(); 11765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId); 11865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 11965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<Client> client; 12065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (cameraId < 0 || cameraId >= mNumberOfCameras) { 12165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).", 12265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian callingPid, cameraId); 12365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NULL; 12465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 12565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 12665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mServiceLock); 12765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mClient[cameraId] != 0) { 12865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client = mClient[cameraId].promote(); 12965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (client != 0) { 13065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) { 13165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("CameraService::connect X (pid %d) (the same client)", 13265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian callingPid); 13365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return client; 13465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 13565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGW("CameraService::connect X (pid %d) rejected (existing client).", 13665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian callingPid); 13765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NULL; 13865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 13965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 14065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClient[cameraId].clear(); 14165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 14265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 14365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mBusy[cameraId]) { 14465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGW("CameraService::connect X (pid %d) rejected" 14565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian " (camera %d is still busy).", callingPid, cameraId); 14665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NULL; 14765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 14865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 149b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li sp<CameraHardwareInterface> hardware = HAL_openCameraHardware(cameraId); 150b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li if (hardware == NULL) { 151b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li LOGE("Fail to open camera hardware (id=%d)", cameraId); 152b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li return NULL; 153b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li } 154b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li client = new Client(this, cameraClient, hardware, cameraId, callingPid); 15565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClient[cameraId] = client; 15665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("CameraService::connect X"); 15765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return client; 15865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 15965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 16065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::removeClient(const sp<ICameraClient>& cameraClient) { 16165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int callingPid = getCallingPid(); 16265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("CameraService::removeClient E (pid %d)", callingPid); 16365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 16465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (int i = 0; i < mNumberOfCameras; i++) { 16565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Declare this before the lock to make absolutely sure the 16665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // destructor won't be called with the lock held. 16765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<Client> client; 16865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 16965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mServiceLock); 17065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 17165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // This happens when we have already disconnected (or this is 17265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // just another unused camera). 17365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mClient[i] == 0) continue; 17465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 17565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Promote mClient. It can fail if we are called from this path: 17665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Client::~Client() -> disconnect() -> removeClient(). 17765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client = mClient[i].promote(); 17865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 17965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (client == 0) { 18065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClient[i].clear(); 18165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian continue; 18265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 18365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 18465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) { 18565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Found our camera, clear and leave. 18665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("removeClient: clear camera %d", i); 18765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClient[i].clear(); 18865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 18965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 19065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 19165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 19265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("CameraService::removeClient X (pid %d)", callingPid); 19365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 19465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 19565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<CameraService::Client> CameraService::getClientById(int cameraId) { 19665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL; 19765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mClient[cameraId].promote(); 19865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 19965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 20065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::onTransact( 20165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { 20265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Permission checks 20365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian switch (code) { 20465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case BnCameraService::CONNECT: 20565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const int pid = getCallingPid(); 20665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const int self_pid = getpid(); 20765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (pid != self_pid) { 20865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // we're called from a different process, do the real check 20965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!checkCallingPermission( 21065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String16("android.permission.CAMERA"))) { 21165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const int uid = getCallingUid(); 21265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("Permission Denial: " 21365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian "can't use the camera pid=%d, uid=%d", pid, uid); 21465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return PERMISSION_DENIED; 21565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 21665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 21765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 21865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 21965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 22065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return BnCameraService::onTransact(code, data, reply, flags); 22165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 22265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 22365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// The reason we need this busy bit is a new CameraService::connect() request 22465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// may come in while the previous Client's destructor has not been run or is 22565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// still running. If the last strong reference of the previous Client is gone 22665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// but the destructor has not been finished, we should not allow the new Client 22765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// to be created because we need to wait for the previous Client to tear down 22865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// the hardware first. 22965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::setCameraBusy(int cameraId) { 23065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian android_atomic_write(1, &mBusy[cameraId]); 23165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 23265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 23365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::setCameraFree(int cameraId) { 23465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian android_atomic_write(0, &mBusy[cameraId]); 23565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 23665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 23765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// We share the media players for shutter and recording sound for all clients. 23865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// A reference count is kept to determine when we will actually release the 23965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// media players. 24065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 24165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic MediaPlayer* newMediaPlayer(const char *file) { 24265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian MediaPlayer* mp = new MediaPlayer(); 24365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mp->setDataSource(file, NULL) == NO_ERROR) { 24465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mp->setAudioStreamType(AudioSystem::ENFORCED_AUDIBLE); 24565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mp->prepare(); 24665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 24765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("Failed to load CameraService sounds: %s", file); 24865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NULL; 24965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 25065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mp; 25165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 25265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 25365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::loadSound() { 25465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mSoundLock); 25565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("CameraService::loadSound ref=%d", mSoundRef); 25665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mSoundRef++) return; 25765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 25865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg"); 25965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg"); 26065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 26165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 26265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::releaseSound() { 26365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mSoundLock); 26465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("CameraService::releaseSound ref=%d", mSoundRef); 26565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (--mSoundRef) return; 26665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 26765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (int i = 0; i < NUM_SOUNDS; i++) { 26865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mSoundPlayer[i] != 0) { 26965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mSoundPlayer[i]->disconnect(); 27065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mSoundPlayer[i].clear(); 27165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 27265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 27365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 27465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 27565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::playSound(sound_kind kind) { 27665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("playSound(%d)", kind); 27765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mSoundLock); 27865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<MediaPlayer> player = mSoundPlayer[kind]; 27965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (player != 0) { 28065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // do not play the sound if stream volume is 0 28165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // (typically because ringer mode is silent). 28265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int index; 28365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian AudioSystem::getStreamVolumeIndex(AudioSystem::ENFORCED_AUDIBLE, &index); 28465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (index != 0) { 28565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian player->seekTo(0); 28665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian player->start(); 28765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 28865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 28965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 29065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 29165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 29265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 29365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::Client(const sp<CameraService>& cameraService, 294b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li const sp<ICameraClient>& cameraClient, 295b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li const sp<CameraHardwareInterface>& hardware, 296b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li int cameraId, int clientPid) { 29765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int callingPid = getCallingPid(); 29865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("Client::Client E (pid %d)", callingPid); 29965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 30065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraService = cameraService; 30165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraClient = cameraClient; 302b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li mHardware = hardware; 30365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraId = cameraId; 30465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClientPid = clientPid; 30565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mUseOverlay = mHardware->useOverlay(); 30665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mMsgEnabled = 0; 30765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 30865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->setCallbacks(notifyCallback, 30965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian dataCallback, 31065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian dataCallbackTimestamp, 31165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian (void *)cameraId); 31265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 31365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Enable zoom, error, and focus messages by default 31465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian enableMsgType(CAMERA_MSG_ERROR | 31565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian CAMERA_MSG_ZOOM | 31665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian CAMERA_MSG_FOCUS); 31765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mOverlayW = 0; 31865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mOverlayH = 0; 31965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 32065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Callback is disabled by default 32165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP; 32265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mOrientation = 0; 323b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra mPlayShutterSound = true; 32465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian cameraService->setCameraBusy(cameraId); 32565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian cameraService->loadSound(); 32665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("Client::Client X (pid %d)", callingPid); 32765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 32865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 32965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic void *unregister_surface(void *arg) { 33065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian ISurface *surface = (ISurface *)arg; 33165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian surface->unregisterBuffers(); 33265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian IPCThreadState::self()->flushCommands(); 33365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NULL; 33465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 33565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 33665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// tear down the client 33765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::~Client() { 33865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int callingPid = getCallingPid(); 33965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("Client::~Client E (pid %d, this %p)", callingPid, this); 34065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 34165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // set mClientPid to let disconnet() tear down the hardware 34265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClientPid = callingPid; 34365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian disconnect(); 34465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraService->releaseSound(); 34565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("Client::~Client X (pid %d, this %p)", callingPid, this); 34665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 34765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 34865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 34965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 35065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::checkPid() const { 35165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int callingPid = getCallingPid(); 35265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (callingPid == mClientPid) return NO_ERROR; 35365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 35465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGW("attempt to use a locked camera from a different process" 35565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian " (old pid %d, new pid %d)", mClientPid, callingPid); 35665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return EBUSY; 35765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 35865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 35965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::checkPidAndHardware() const { 36065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = checkPid(); 36165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) return result; 36265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mHardware == 0) { 36365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("attempt to use a camera after disconnect() (pid %d)", getCallingPid()); 36465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return INVALID_OPERATION; 36565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 36665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 36765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 36865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 36965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::lock() { 37065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int callingPid = getCallingPid(); 37165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("lock (pid %d)", callingPid); 37265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 37365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 37465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // lock camera to this client if the the camera is unlocked 37565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mClientPid == 0) { 37665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClientPid = callingPid; 37765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 37865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 37965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 38065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // returns NO_ERROR if the client already owns the camera, EBUSY otherwise 38165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return checkPid(); 38265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 38365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 38465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::unlock() { 38565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int callingPid = getCallingPid(); 38665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("unlock (pid %d)", callingPid); 38765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 38865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 38965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // allow anyone to use camera (after they lock the camera) 39065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = checkPid(); 39165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result == NO_ERROR) { 39265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClientPid = 0; 39365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("clear mCameraClient (pid %d)", callingPid); 39465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // we need to remove the reference to ICameraClient so that when the app 39565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // goes away, the reference count goes to 0. 39665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraClient.clear(); 39765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 39865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return result; 39965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 40065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 40165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// connect a new client to the camera 40265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::connect(const sp<ICameraClient>& client) { 40365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int callingPid = getCallingPid(); 40465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("connect E (pid %d)", callingPid); 40565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 40665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 40765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mClientPid != 0 && checkPid() != NO_ERROR) { 40865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGW("Tried to connect to a locked camera (old pid %d, new pid %d)", 40965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClientPid, callingPid); 41065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return EBUSY; 41165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 41265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 41365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mCameraClient != 0 && (client->asBinder() == mCameraClient->asBinder())) { 41465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("Connect to the same client"); 41565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 41665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 41765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 41865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP; 41965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClientPid = callingPid; 42065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraClient = client; 42165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 42265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("connect X (pid %d)", callingPid); 42365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 42465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 42565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 42665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::disconnect() { 42765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int callingPid = getCallingPid(); 42865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("disconnect E (pid %d)", callingPid); 42965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 43065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 43165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (checkPid() != NO_ERROR) { 43265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGW("different client - don't disconnect"); 43365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return; 43465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 43565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 43665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mClientPid <= 0) { 43765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("camera is unlocked (mClientPid = %d), don't tear down hardware", mClientPid); 43865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return; 43965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 44065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 44165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Make sure disconnect() is done once and once only, whether it is called 44265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // from the user directly, or called by the destructor. 44365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mHardware == 0) return; 44465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 44565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("hardware teardown"); 44665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Before destroying mHardware, we must make sure it's in the 44765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // idle state. 44865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Turn off all messages. 44965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian disableMsgType(CAMERA_MSG_ALL_MSGS); 45065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->stopPreview(); 45165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->cancelPicture(); 45265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Release the hardware resources. 45365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->release(); 45465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Release the held overlay resources. 45565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mUseOverlay) { 45665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mOverlayRef = 0; 45765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 4584b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis // Release the held ANativeWindow resources. 4594b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis if (mPreviewWindow != 0) { 4604b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis mPreviewWindow = 0; 4614b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis mHardware->setPreviewWindow(mPreviewWindow); 4624b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis } 46365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware.clear(); 46465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 46565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraService->removeClient(mCameraClient); 46665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraService->setCameraFree(mCameraId); 46765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 46865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("disconnect X (pid %d)", callingPid); 46965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 47065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 47165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 47265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 4734b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis// set the Surface that the preview will use 4744b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennisstatus_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) { 47565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid()); 47665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 47765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = checkPidAndHardware(); 47865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) return result; 47965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 48065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result = NO_ERROR; 48165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 48265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // return if no change in surface. 48365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // asBinder() is safe on NULL (returns NULL) 4844b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis if (getISurface(surface)->asBinder() == mSurface->asBinder()) { 48565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return result; 48665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 48765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 48865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mSurface != 0) { 48965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("clearing old preview surface %p", mSurface.get()); 49065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mUseOverlay) { 49165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Force the destruction of any previous overlay 49265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<Overlay> dummy; 49365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->setOverlay(dummy); 49465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 49565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 4964b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis if (surface != 0) { 4974b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis mSurface = getISurface(surface); 4984b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis } else { 4994b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis mSurface = 0; 5004b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis } 5014b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis mPreviewWindow = surface; 50265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mOverlayRef = 0; 50365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // If preview has been already started, set overlay or register preview 50465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // buffers now. 50565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mHardware->previewEnabled()) { 50665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mUseOverlay) { 50765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result = setOverlay(); 5084b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis } else if (mPreviewWindow != 0) { 5094b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis result = mHardware->setPreviewWindow(mPreviewWindow); 51065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 51165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 51265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 51365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return result; 51465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 51565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 51665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::setOverlay() { 51765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int w, h; 51865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian CameraParameters params(mHardware->getParameters()); 51965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian params.getPreviewSize(&w, &h); 52065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 52165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (w != mOverlayW || h != mOverlayH) { 52265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Force the destruction of any previous overlay 52365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<Overlay> dummy; 52465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->setOverlay(dummy); 52565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mOverlayRef = 0; 52665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 52765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 52865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = NO_ERROR; 52965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mSurface == 0) { 53065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result = mHardware->setOverlay(NULL); 53165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 53265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mOverlayRef == 0) { 53365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // FIXME: 53465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Surfaceflinger may hold onto the previous overlay reference for some 53565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // time after we try to destroy it. retry a few times. In the future, we 53665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // should make the destroy call block, or possibly specify that we can 53765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // wait in the createOverlay call if the previous overlay is in the 53865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // process of being destroyed. 53965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (int retry = 0; retry < 50; ++retry) { 54065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mOverlayRef = mSurface->createOverlay(w, h, OVERLAY_FORMAT_DEFAULT, 54165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mOrientation); 54265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mOverlayRef != 0) break; 54365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGW("Overlay create failed - retrying"); 54465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian usleep(20000); 54565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 54665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mOverlayRef == 0) { 54765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("Overlay Creation Failed!"); 54865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return -EINVAL; 54965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 55065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result = mHardware->setOverlay(new Overlay(mOverlayRef)); 55165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 55265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 55365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) { 55465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("mHardware->setOverlay() failed with status %d\n", result); 55565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return result; 55665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 55765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 55865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mOverlayW = w; 55965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mOverlayH = h; 56065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 56165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return result; 56265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 56365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 56465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// set the preview callback flag to affect how the received frames from 56565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// preview are handled. 56665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::setPreviewCallbackFlag(int callback_flag) { 56765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("setPreviewCallbackFlag(%d) (pid %d)", callback_flag, getCallingPid()); 56865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 56965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (checkPidAndHardware() != NO_ERROR) return; 57065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 57165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mPreviewCallbackFlag = callback_flag; 5720667de7038238c31af77865eb6d83c5ae9ca1b1eWu-cheng Li if (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ENABLE_MASK) { 5730667de7038238c31af77865eb6d83c5ae9ca1b1eWu-cheng Li enableMsgType(CAMERA_MSG_PREVIEW_FRAME); 5740667de7038238c31af77865eb6d83c5ae9ca1b1eWu-cheng Li } else { 5750667de7038238c31af77865eb6d83c5ae9ca1b1eWu-cheng Li disableMsgType(CAMERA_MSG_PREVIEW_FRAME); 57665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 57765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 57865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 57965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// start preview mode 58065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::startPreview() { 58165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("startPreview (pid %d)", getCallingPid()); 58265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return startCameraMode(CAMERA_PREVIEW_MODE); 58365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 58465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 58565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// start recording mode 58665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::startRecording() { 58765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("startRecording (pid %d)", getCallingPid()); 58865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return startCameraMode(CAMERA_RECORDING_MODE); 58965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 59065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 59165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// start preview or recording 59265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::startCameraMode(camera_mode mode) { 59365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("startCameraMode(%d)", mode); 59465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 59565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = checkPidAndHardware(); 59665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) return result; 59765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 59865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian switch(mode) { 59965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case CAMERA_PREVIEW_MODE: 6004b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis if (mSurface == 0 && mPreviewWindow == 0) { 60165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("mSurface is not set yet."); 60265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // still able to start preview in this case. 60365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 60465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return startPreviewMode(); 60565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case CAMERA_RECORDING_MODE: 6064b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis if (mSurface == 0 && mPreviewWindow == 0) { 6074b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis LOGE("mSurface or mPreviewWindow must be set before startRecordingMode."); 60865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return INVALID_OPERATION; 60965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 61065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return startRecordingMode(); 61165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian default: 61265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return UNKNOWN_ERROR; 61365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 61465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 61565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 61665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::startPreviewMode() { 61765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("startPreviewMode"); 61865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = NO_ERROR; 61965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 62065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // if preview has been enabled, nothing needs to be done 62165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mHardware->previewEnabled()) { 62265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 62365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 62465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 62565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mUseOverlay) { 62665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // If preview display has been set, set overlay now. 62765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mSurface != 0) { 62865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result = setOverlay(); 62965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 63065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) return result; 63165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result = mHardware->startPreview(); 63265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 6334b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis // XXX: Set the orientation of the ANativeWindow. 6344b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis mHardware->setPreviewWindow(mPreviewWindow); 63565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result = mHardware->startPreview(); 63665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 63765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return result; 63865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 63965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 64065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::startRecordingMode() { 64165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("startRecordingMode"); 64265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = NO_ERROR; 64365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 64465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // if recording has been enabled, nothing needs to be done 64565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mHardware->recordingEnabled()) { 64665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 64765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 64865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 64965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // if preview has not been started, start preview first 65065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!mHardware->previewEnabled()) { 65165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result = startPreviewMode(); 65265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) { 65365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return result; 65465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 65565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 65665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 65765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // start recording mode 65865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian enableMsgType(CAMERA_MSG_VIDEO_FRAME); 65965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraService->playSound(SOUND_RECORDING); 66065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result = mHardware->startRecording(); 66165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) { 66265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("mHardware->startRecording() failed with status %d", result); 66365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 66465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return result; 66565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 66665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 66765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// stop preview mode 66865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::stopPreview() { 66965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("stopPreview (pid %d)", getCallingPid()); 67065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 67165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (checkPidAndHardware() != NO_ERROR) return; 67265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 6734b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis 67465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian disableMsgType(CAMERA_MSG_PREVIEW_FRAME); 67565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->stopPreview(); 67665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 67765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mPreviewBuffer.clear(); 67865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 67965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 68065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// stop recording mode 68165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::stopRecording() { 68265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("stopRecording (pid %d)", getCallingPid()); 68365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 68465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (checkPidAndHardware() != NO_ERROR) return; 68565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 68665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraService->playSound(SOUND_RECORDING); 68765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian disableMsgType(CAMERA_MSG_VIDEO_FRAME); 68865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->stopRecording(); 68965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 69065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mPreviewBuffer.clear(); 69165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 69265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 69365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// release a recording frame 69465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::releaseRecordingFrame(const sp<IMemory>& mem) { 69565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 69665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (checkPidAndHardware() != NO_ERROR) return; 69765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->releaseRecordingFrame(mem); 69865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 69965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 70065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool CameraService::Client::previewEnabled() { 70165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("previewEnabled (pid %d)", getCallingPid()); 70265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 70365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 70465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (checkPidAndHardware() != NO_ERROR) return false; 70565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mHardware->previewEnabled(); 70665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 70765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 70865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool CameraService::Client::recordingEnabled() { 70965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("recordingEnabled (pid %d)", getCallingPid()); 71065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 71165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 71265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (checkPidAndHardware() != NO_ERROR) return false; 71365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mHardware->recordingEnabled(); 71465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 71565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 71665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::autoFocus() { 71765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("autoFocus (pid %d)", getCallingPid()); 71865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 71965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 72065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = checkPidAndHardware(); 72165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) return result; 72265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 72365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mHardware->autoFocus(); 72465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 72565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 72665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::cancelAutoFocus() { 72765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("cancelAutoFocus (pid %d)", getCallingPid()); 72865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 72965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 73065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = checkPidAndHardware(); 73165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) return result; 73265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 73365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mHardware->cancelAutoFocus(); 73465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 73565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 73665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// take a picture - image is returned in callback 73765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::takePicture() { 73865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("takePicture (pid %d)", getCallingPid()); 73965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 74065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 74165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = checkPidAndHardware(); 74265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) return result; 74365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 74465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian enableMsgType(CAMERA_MSG_SHUTTER | 74565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian CAMERA_MSG_POSTVIEW_FRAME | 74665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian CAMERA_MSG_RAW_IMAGE | 74765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian CAMERA_MSG_COMPRESSED_IMAGE); 74865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 74965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mHardware->takePicture(); 75065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 75165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 75265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// set preview/capture parameters - key/value pairs 75365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::setParameters(const String8& params) { 75465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("setParameters (pid %d) (%s)", getCallingPid(), params.string()); 75565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 75665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 75765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = checkPidAndHardware(); 75865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) return result; 75965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 76065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian CameraParameters p(params); 76165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mHardware->setParameters(p); 76265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 76365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 76465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// get preview/capture parameters - key/value pairs 76565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianString8 CameraService::Client::getParameters() const { 76665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 76765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (checkPidAndHardware() != NO_ERROR) return String8(); 76865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 76965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 params(mHardware->getParameters().flatten()); 77065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("getParameters (pid %d) (%s)", getCallingPid(), params.string()); 77165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return params; 77265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 77365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 774b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra// enable shutter sound 775b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatrastatus_t CameraService::Client::enableShutterSound(bool enable) { 776b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra LOG1("enableShutterSound (pid %d)", getCallingPid()); 777b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra 778b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra status_t result = checkPidAndHardware(); 779b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra if (result != NO_ERROR) return result; 780b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra 781b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra if (enable) { 782b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra mPlayShutterSound = true; 783b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra return OK; 784b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra } 785b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra 786b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra // Disabling shutter sound may not be allowed. In that case only 787b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra // allow the mediaserver process to disable the sound. 788b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra char value[PROPERTY_VALUE_MAX]; 789b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra property_get("ro.camera.sound.forced", value, "0"); 790b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra if (strcmp(value, "0") != 0) { 791b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra // Disabling shutter sound is not allowed. Deny if the current 792b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra // process is not mediaserver. 793b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra if (getCallingPid() != getpid()) { 794b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra LOGE("Failed to disable shutter sound. Permission denied (pid %d)", getCallingPid()); 795b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra return PERMISSION_DENIED; 796b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra } 797b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra } 798b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra 799b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra mPlayShutterSound = false; 800b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra return OK; 801b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra} 802b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra 80365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) { 80465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("sendCommand (pid %d)", getCallingPid()); 80565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 80665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = checkPidAndHardware(); 80765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) return result; 80865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 80965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) { 81065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // The orientation cannot be set during preview. 81165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mHardware->previewEnabled()) { 81265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return INVALID_OPERATION; 81365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 81465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian switch (arg1) { 81565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case 0: 81665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mOrientation = ISurface::BufferHeap::ROT_0; 81765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 81865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case 90: 81965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mOrientation = ISurface::BufferHeap::ROT_90; 82065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 82165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case 180: 82265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mOrientation = ISurface::BufferHeap::ROT_180; 82365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 82465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case 270: 82565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mOrientation = ISurface::BufferHeap::ROT_270; 82665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 82765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian default: 82865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return BAD_VALUE; 82965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 83065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return OK; 831b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra } else if (cmd == CAMERA_CMD_ENABLE_SHUTTER_SOUND) { 832b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra switch (arg1) { 833b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra case 0: 834b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra enableShutterSound(false); 835b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra break; 836b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra case 1: 837b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra enableShutterSound(true); 838b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra break; 839b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra default: 840b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra return BAD_VALUE; 841b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra } 842b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra return OK; 84365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 84465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 84565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mHardware->sendCommand(cmd, arg1, arg2); 84665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 84765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 84865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 84965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 85065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::enableMsgType(int32_t msgType) { 85165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian android_atomic_or(msgType, &mMsgEnabled); 85265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->enableMsgType(msgType); 85365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 85465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 85565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::disableMsgType(int32_t msgType) { 85665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian android_atomic_and(~msgType, &mMsgEnabled); 85765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->disableMsgType(msgType); 85865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 85965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 86065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define CHECK_MESSAGE_INTERVAL 10 // 10ms 86165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool CameraService::Client::lockIfMessageWanted(int32_t msgType) { 86265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int sleepCount = 0; 86365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian while (mMsgEnabled & msgType) { 86465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mLock.tryLock() == NO_ERROR) { 86565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (sleepCount > 0) { 86665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("lockIfMessageWanted(%d): waited for %d ms", 86765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian msgType, sleepCount * CHECK_MESSAGE_INTERVAL); 86865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 86965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return true; 87065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 87165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (sleepCount++ == 0) { 87265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("lockIfMessageWanted(%d): enter sleep", msgType); 87365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 87465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian usleep(CHECK_MESSAGE_INTERVAL * 1000); 87565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 87665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGW("lockIfMessageWanted(%d): dropped unwanted message", msgType); 87765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return false; 87865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 87965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 88065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 88165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 88265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Converts from a raw pointer to the client to a strong pointer during a 88365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// hardware callback. This requires the callbacks only happen when the client 88465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// is still alive. 88565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<CameraService::Client> CameraService::Client::getClientFromCookie(void* user) { 88665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<Client> client = gCameraService->getClientById((int) user); 88765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 88865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // This could happen if the Client is in the process of shutting down (the 88965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // last strong reference is gone, but the destructor hasn't finished 89065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // stopping the hardware). 89165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (client == 0) return NULL; 89265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 89365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // The checks below are not necessary and are for debugging only. 89465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (client->mCameraService.get() != gCameraService) { 89565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("mismatch service!"); 89665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NULL; 89765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 89865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 89965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (client->mHardware == 0) { 90065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("mHardware == 0: callback after disconnect()?"); 90165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NULL; 90265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 90365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 90465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return client; 90565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 90665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 90765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Callback messages can be dispatched to internal handlers or pass to our 90865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// client's callback functions, depending on the message type. 90965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// 91065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// notifyCallback: 91165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// CAMERA_MSG_SHUTTER handleShutter 91265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// (others) c->notifyCallback 91365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// dataCallback: 91465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// CAMERA_MSG_PREVIEW_FRAME handlePreviewData 91565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// CAMERA_MSG_POSTVIEW_FRAME handlePostview 91665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// CAMERA_MSG_RAW_IMAGE handleRawPicture 91765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// CAMERA_MSG_COMPRESSED_IMAGE handleCompressedPicture 91865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// (others) c->dataCallback 91965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// dataCallbackTimestamp 92065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// (others) c->dataCallbackTimestamp 92165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// 92265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// NOTE: the *Callback functions grab mLock of the client before passing 92365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// control to handle* functions. So the handle* functions must release the 92465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// lock before calling the ICameraClient's callbacks, so those callbacks can 92565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// invoke methods in the Client class again (For example, the preview frame 92665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// callback may want to releaseRecordingFrame). The handle* functions must 92765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// release the lock after all accesses to member variables, so it must be 92865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// handled very carefully. 92965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 93065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::notifyCallback(int32_t msgType, int32_t ext1, 93165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t ext2, void* user) { 93265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG2("notifyCallback(%d)", msgType); 93365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 93465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<Client> client = getClientFromCookie(user); 93565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (client == 0) return; 93665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!client->lockIfMessageWanted(msgType)) return; 93765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 93865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian switch (msgType) { 93965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case CAMERA_MSG_SHUTTER: 94065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // ext1 is the dimension of the yuv picture. 94165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->handleShutter((image_rect_type *)ext1); 94265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 94365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian default: 94465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->handleGenericNotify(msgType, ext1, ext2); 94565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 94665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 94765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 94865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 94965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::dataCallback(int32_t msgType, 95065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const sp<IMemory>& dataPtr, void* user) { 95165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG2("dataCallback(%d)", msgType); 95265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 95365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<Client> client = getClientFromCookie(user); 95465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (client == 0) return; 95565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!client->lockIfMessageWanted(msgType)) return; 95665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 95765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (dataPtr == 0) { 95865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("Null data returned in data callback"); 95965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); 96065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return; 96165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 96265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 96365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian switch (msgType) { 96465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case CAMERA_MSG_PREVIEW_FRAME: 96565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->handlePreviewData(dataPtr); 96665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 96765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case CAMERA_MSG_POSTVIEW_FRAME: 96865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->handlePostview(dataPtr); 96965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 97065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case CAMERA_MSG_RAW_IMAGE: 97165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->handleRawPicture(dataPtr); 97265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 97365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case CAMERA_MSG_COMPRESSED_IMAGE: 97465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->handleCompressedPicture(dataPtr); 97565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 97665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian default: 97765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->handleGenericData(msgType, dataPtr); 97865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 97965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 98065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 98165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 98265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::dataCallbackTimestamp(nsecs_t timestamp, 98365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t msgType, const sp<IMemory>& dataPtr, void* user) { 98465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG2("dataCallbackTimestamp(%d)", msgType); 98565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 98665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<Client> client = getClientFromCookie(user); 98765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (client == 0) return; 98865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!client->lockIfMessageWanted(msgType)) return; 98965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 99065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (dataPtr == 0) { 99165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("Null data returned in data with timestamp callback"); 99265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); 99365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return; 99465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 99565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 99665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->handleGenericDataTimestamp(timestamp, msgType, dataPtr); 99765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 99865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 99965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// snapshot taken callback 100065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// "size" is the width and height of yuv picture for registerBuffer. 100165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// If it is NULL, use the picture size from parameters. 100265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handleShutter(image_rect_type *size) { 1003b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra if (mPlayShutterSound) { 1004b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra mCameraService->playSound(SOUND_SHUTTER); 1005b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra } 100665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 100765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<ICameraClient> c = mCameraClient; 100865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (c != 0) { 100965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 101065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0); 101165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!lockIfMessageWanted(CAMERA_MSG_SHUTTER)) return; 101265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 101365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian disableMsgType(CAMERA_MSG_SHUTTER); 101465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 101565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // It takes some time before yuvPicture callback to be called. 101665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Register the buffer for raw image here to reduce latency. 101765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mSurface != 0 && !mUseOverlay) { 101865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int w, h; 101965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian CameraParameters params(mHardware->getParameters()); 102065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (size == NULL) { 102165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian params.getPictureSize(&w, &h); 102265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 102365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian w = size->width; 102465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian h = size->height; 102565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian w &= ~1; 102665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian h &= ~1; 102765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("Snapshot image width=%d, height=%d", w, h); 102865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 102965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // FIXME: don't use hardcoded format constants here 103065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian ISurface::BufferHeap buffers(w, h, w, h, 103165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian HAL_PIXEL_FORMAT_YCrCb_420_SP, mOrientation, 0, 103265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->getRawHeap()); 103365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 103465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian IPCThreadState::self()->flushCommands(); 103565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 103665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 103765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 103865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 103965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 104065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// preview callback - frame buffer update 104165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handlePreviewData(const sp<IMemory>& mem) { 104265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian ssize_t offset; 104365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian size_t size; 104465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); 104565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 104665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // local copy of the callback flags 104765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int flags = mPreviewCallbackFlag; 104865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 104965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // is callback enabled? 105065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!(flags & FRAME_CALLBACK_FLAG_ENABLE_MASK)) { 105165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // If the enable bit is off, the copy-out and one-shot bits are ignored 105265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG2("frame callback is disabled"); 105365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 105465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return; 105565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 105665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 105765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // hold a strong pointer to the client 105865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<ICameraClient> c = mCameraClient; 105965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 106065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // clear callback flags if no client or one-shot mode 106165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (c == 0 || (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) { 106265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG2("Disable preview callback"); 106365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mPreviewCallbackFlag &= ~(FRAME_CALLBACK_FLAG_ONE_SHOT_MASK | 106465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian FRAME_CALLBACK_FLAG_COPY_OUT_MASK | 106565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian FRAME_CALLBACK_FLAG_ENABLE_MASK); 10660667de7038238c31af77865eb6d83c5ae9ca1b1eWu-cheng Li disableMsgType(CAMERA_MSG_PREVIEW_FRAME); 106765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 106865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 106965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (c != 0) { 107065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Is the received frame copied out or not? 107165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (flags & FRAME_CALLBACK_FLAG_COPY_OUT_MASK) { 107265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG2("frame is copied"); 107365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian copyFrameAndPostCopiedFrame(c, heap, offset, size); 107465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 107565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG2("frame is forwarded"); 107665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 107765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian c->dataCallback(CAMERA_MSG_PREVIEW_FRAME, mem); 107865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 107965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 108065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 108165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 108265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 108365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 108465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// picture callback - postview image ready 108565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handlePostview(const sp<IMemory>& mem) { 108665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian disableMsgType(CAMERA_MSG_POSTVIEW_FRAME); 108765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 108865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<ICameraClient> c = mCameraClient; 108965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 109065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (c != 0) { 109165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem); 109265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 109365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 109465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 109565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// picture callback - raw image ready 109665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handleRawPicture(const sp<IMemory>& mem) { 109765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian disableMsgType(CAMERA_MSG_RAW_IMAGE); 109865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 109965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian ssize_t offset; 110065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian size_t size; 110165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); 110265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 110365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<ICameraClient> c = mCameraClient; 110465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 110565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (c != 0) { 110665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem); 110765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 110865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 110965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 111065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// picture callback - compressed picture ready 111165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handleCompressedPicture(const sp<IMemory>& mem) { 111265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE); 111365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 111465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<ICameraClient> c = mCameraClient; 111565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 111665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (c != 0) { 111765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem); 111865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 111965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 112065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 112165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 112265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handleGenericNotify(int32_t msgType, 112365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t ext1, int32_t ext2) { 112465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<ICameraClient> c = mCameraClient; 112565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 112665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (c != 0) { 112765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian c->notifyCallback(msgType, ext1, ext2); 112865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 112965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 113065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 113165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handleGenericData(int32_t msgType, 113265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const sp<IMemory>& dataPtr) { 113365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<ICameraClient> c = mCameraClient; 113465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 113565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (c != 0) { 113665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian c->dataCallback(msgType, dataPtr); 113765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 113865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 113965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 114065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handleGenericDataTimestamp(nsecs_t timestamp, 114165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t msgType, const sp<IMemory>& dataPtr) { 114265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<ICameraClient> c = mCameraClient; 114365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 114465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (c != 0) { 114565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian c->dataCallbackTimestamp(timestamp, msgType, dataPtr); 114665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 114765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 114865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 114965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::copyFrameAndPostCopiedFrame( 115065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const sp<ICameraClient>& client, const sp<IMemoryHeap>& heap, 115165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian size_t offset, size_t size) { 115265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG2("copyFrameAndPostCopiedFrame"); 115365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // It is necessary to copy out of pmem before sending this to 115465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // the callback. For efficiency, reuse the same MemoryHeapBase 115565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // provided it's big enough. Don't allocate the memory or 115665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // perform the copy if there's no callback. 115765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // hold the preview lock while we grab a reference to the preview buffer 115865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<MemoryHeapBase> previewBuffer; 115965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 116065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mPreviewBuffer == 0) { 116165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mPreviewBuffer = new MemoryHeapBase(size, 0, NULL); 116265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else if (size > mPreviewBuffer->virtualSize()) { 116365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mPreviewBuffer.clear(); 116465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mPreviewBuffer = new MemoryHeapBase(size, 0, NULL); 116565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 116665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mPreviewBuffer == 0) { 116765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("failed to allocate space for preview buffer"); 116865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 116965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return; 117065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 117165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian previewBuffer = mPreviewBuffer; 117265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 117365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian memcpy(previewBuffer->base(), (uint8_t *)heap->base() + offset, size); 117465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 117565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size); 117665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (frame == 0) { 117765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("failed to allocate space for frame callback"); 117865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 117965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return; 118065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 118165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 118265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 118365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->dataCallback(CAMERA_MSG_PREVIEW_FRAME, frame); 118465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 118565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 118665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 118765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 118865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50; 118965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockSleep = 60000; 119065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 119165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic bool tryLock(Mutex& mutex) 119265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 119365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian bool locked = false; 119465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (int i = 0; i < kDumpLockRetries; ++i) { 119565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mutex.tryLock() == NO_ERROR) { 119665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian locked = true; 119765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 119865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 119965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian usleep(kDumpLockSleep); 120065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 120165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return locked; 120265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 120365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 120465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::dump(int fd, const Vector<String16>& args) { 120565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian static const char* kDeadlockedString = "CameraService may be deadlocked\n"; 120665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 120765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const size_t SIZE = 256; 120865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian char buffer[SIZE]; 120965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result; 121065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (checkCallingPermission(String16("android.permission.DUMP")) == false) { 121165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "Permission Denial: " 121265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian "can't dump CameraService from pid=%d, uid=%d\n", 121365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian getCallingPid(), 121465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian getCallingUid()); 121565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 121665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 121765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 121865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian bool locked = tryLock(mServiceLock); 121965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // failed to lock - CameraService is probably deadlocked 122065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!locked) { 122165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result(kDeadlockedString); 122265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 122365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 122465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 122565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian bool hasClient = false; 122665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (int i = 0; i < mNumberOfCameras; i++) { 122765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<Client> client = mClient[i].promote(); 122865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (client == 0) continue; 122965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian hasClient = true; 123065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sprintf(buffer, "Client[%d] (%p) PID: %d\n", 123165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian i, 123265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->getCameraClient()->asBinder().get(), 123365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->mClientPid); 123465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 123565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 123665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->mHardware->dump(fd, args); 123765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 123865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!hasClient) { 123965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append("No camera client yet.\n"); 124065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 124165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 124265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 124365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (locked) mServiceLock.unlock(); 124465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 124565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // change logging level 124665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int n = args.size(); 124765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (int i = 0; i + 1 < n; i++) { 124865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (args[i] == String16("-v")) { 124965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 levelStr(args[i+1]); 125065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int level = atoi(levelStr.string()); 125165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sprintf(buffer, "Set Log Level to %d", level); 125265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 125365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian setLogLevel(level); 125465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 125565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 125665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 125765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 125865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 125965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 12604b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennissp<ISurface> CameraService::getISurface(const sp<Surface>& surface) { 12614b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis if (surface != 0) { 12624b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis return surface->getISurface(); 12634b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis } else { 12644b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis return sp<ISurface>(0); 12654b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis } 12664b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis} 12674b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis 126865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android 1269