CameraService.cpp revision 9bc7af17974f448291a44912566ec7472a0d798b
165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian/* 265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** 365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** Copyright (C) 2008, The Android Open Source Project 465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** 565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** Licensed under the Apache License, Version 2.0 (the "License"); 665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** you may not use this file except in compliance with the License. 765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** You may obtain a copy of the License at 865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** 965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** http://www.apache.org/licenses/LICENSE-2.0 1065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** 1165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** Unless required by applicable law or agreed to in writing, software 1265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** distributed under the License is distributed on an "AS IS" BASIS, 1365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** See the License for the specific language governing permissions and 1565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian** limitations under the License. 1665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian*/ 1765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG_TAG "CameraService" 198951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev//#define LOG_NDEBUG 0 2065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 2165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <stdio.h> 2265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <sys/types.h> 2365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <pthread.h> 2465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 2565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IPCThreadState.h> 2665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/IServiceManager.h> 2765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/MemoryBase.h> 2865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <binder/MemoryHeapBase.h> 2965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <cutils/atomic.h> 30b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra#include <cutils/properties.h> 31bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis#include <gui/SurfaceTextureClient.h> 3265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <hardware/hardware.h> 3365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/AudioSystem.h> 3465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/mediaplayer.h> 3565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <surfaceflinger/ISurface.h> 3665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Errors.h> 3765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Log.h> 3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/String16.h> 3965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 4065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "CameraService.h" 418951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev#include "CameraHardwareInterface.h" 4265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 4365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiannamespace android { 4465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 4565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 4665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Logging support -- this is for debugging only 4765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Use "adb shell dumpsys media.camera -v 1" to change it. 4865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic volatile int32_t gLogLevel = 0; 4965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG1(...) LOGD_IF(gLogLevel >= 1, __VA_ARGS__); 5165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define LOG2(...) LOGD_IF(gLogLevel >= 2, __VA_ARGS__); 5265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic void setLogLevel(int level) { 5465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian android_atomic_write(level, &gLogLevel); 5565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 5665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 5865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic int getCallingPid() { 6065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return IPCThreadState::self()->getCallingPid(); 6165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 6265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 6365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic int getCallingUid() { 6465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return IPCThreadState::self()->getCallingUid(); 6565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 6665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 6765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 6865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 6965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// This is ugly and only safe if we never re-create the CameraService, but 7065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// should be ok for now. 7165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic CameraService *gCameraService; 7265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 7365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::CameraService() 748951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev:mSoundRef(0), mModule(0) 7565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 7665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGI("CameraService started (pid=%d)", getpid()); 778951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev gCameraService = this; 788951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev} 7965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 808951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchevvoid CameraService::onFirstRef() 818951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev{ 828951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev BnCameraService::onFirstRef(); 8365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 848951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev if (hw_get_module(CAMERA_HARDWARE_MODULE_ID, 858951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev (const hw_module_t **)&mModule) < 0) { 868951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev LOGE("Could not load camera HAL module"); 878951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev mNumberOfCameras = 0; 888951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev } 898951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev else { 908951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev mNumberOfCameras = mModule->get_number_of_cameras(); 918951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev if (mNumberOfCameras > MAX_CAMERAS) { 928951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev LOGE("Number of cameras(%d) > MAX_CAMERAS(%d).", 938951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev mNumberOfCameras, MAX_CAMERAS); 948951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev mNumberOfCameras = MAX_CAMERAS; 958951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev } 968951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev for (int i = 0; i < mNumberOfCameras; i++) { 978951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev setCameraFree(i); 988951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev } 9965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 10065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 10165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 10265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::~CameraService() { 10365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (int i = 0; i < mNumberOfCameras; i++) { 10465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mBusy[i]) { 10565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("camera %d is still in use in destructor!", i); 10665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 10765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 10865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 10965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian gCameraService = NULL; 11065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 11165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 11265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianint32_t CameraService::getNumberOfCameras() { 11365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mNumberOfCameras; 11465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 11565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 11665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::getCameraInfo(int cameraId, 11765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian struct CameraInfo* cameraInfo) { 1188951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev if (!mModule) { 1198951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev return NO_INIT; 1208951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev } 1218951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev 12265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (cameraId < 0 || cameraId >= mNumberOfCameras) { 12365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return BAD_VALUE; 12465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 12565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1268951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev struct camera_info info; 1278951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev status_t rc = mModule->get_camera_info(cameraId, &info); 1288951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev cameraInfo->facing = info.facing; 1298951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev cameraInfo->orientation = info.orientation; 1308951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev return rc; 13165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 13265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 13365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<ICamera> CameraService::connect( 13465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const sp<ICameraClient>& cameraClient, int cameraId) { 13565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int callingPid = getCallingPid(); 13665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId); 13765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1388951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev if (!mModule) { 1398951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev LOGE("Camera HAL module not loaded"); 1408951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev return NULL; 1418951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev } 1428951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev 14365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<Client> client; 14465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (cameraId < 0 || cameraId >= mNumberOfCameras) { 14565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).", 14665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian callingPid, cameraId); 14765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NULL; 14865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 14965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 150a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li char value[PROPERTY_VALUE_MAX]; 151a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li property_get("sys.secpolicy.camera.disabled", value, "0"); 152a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li if (strcmp(value, "1") == 0) { 153a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li // Camera is disabled by DevicePolicyManager. 154a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li LOGI("Camera is disabled. connect X (pid %d) rejected", callingPid); 155a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li return NULL; 156a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li } 157a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li 15865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mServiceLock); 15965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mClient[cameraId] != 0) { 16065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client = mClient[cameraId].promote(); 16165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (client != 0) { 16265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) { 16365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("CameraService::connect X (pid %d) (the same client)", 16465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian callingPid); 16565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return client; 16665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 16765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGW("CameraService::connect X (pid %d) rejected (existing client).", 16865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian callingPid); 16965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NULL; 17065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 17165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 17265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClient[cameraId].clear(); 17365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 17465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 17565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mBusy[cameraId]) { 17665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGW("CameraService::connect X (pid %d) rejected" 17765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian " (camera %d is still busy).", callingPid, cameraId); 17865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NULL; 17965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 18065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1818951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev struct camera_info info; 1828951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev if (mModule->get_camera_info(cameraId, &info) != OK) { 1838951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev LOGE("Invalid camera id %d", cameraId); 184b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li return NULL; 185b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li } 1868951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev 1878951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev char camera_device_name[10]; 1888951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev snprintf(camera_device_name, sizeof(camera_device_name), "%d", cameraId); 1898951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev 1908951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev client = new Client(this, cameraClient, 1918951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev new CameraHardwareInterface(&mModule->common, 1928951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev camera_device_name), 1938951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev cameraId, info.facing, callingPid); 19465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClient[cameraId] = client; 19565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("CameraService::connect X"); 19665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return client; 19765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 19865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 19965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::removeClient(const sp<ICameraClient>& cameraClient) { 20065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int callingPid = getCallingPid(); 20165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("CameraService::removeClient E (pid %d)", callingPid); 20265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 20365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (int i = 0; i < mNumberOfCameras; i++) { 20465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Declare this before the lock to make absolutely sure the 20565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // destructor won't be called with the lock held. 20665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<Client> client; 20765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 20865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mServiceLock); 20965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 21065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // This happens when we have already disconnected (or this is 21165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // just another unused camera). 21265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mClient[i] == 0) continue; 21365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 21465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Promote mClient. It can fail if we are called from this path: 21565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Client::~Client() -> disconnect() -> removeClient(). 21665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client = mClient[i].promote(); 21765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 21865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (client == 0) { 21965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClient[i].clear(); 22065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian continue; 22165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 22265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 22365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) { 22465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Found our camera, clear and leave. 22565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("removeClient: clear camera %d", i); 22665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClient[i].clear(); 22765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 22865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 22965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 23065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 23165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("CameraService::removeClient X (pid %d)", callingPid); 23265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 23365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 23465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<CameraService::Client> CameraService::getClientById(int cameraId) { 23565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL; 23665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mClient[cameraId].promote(); 23765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 23865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 23965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::onTransact( 24065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { 24165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Permission checks 24265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian switch (code) { 24365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case BnCameraService::CONNECT: 24465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const int pid = getCallingPid(); 24565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const int self_pid = getpid(); 24665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (pid != self_pid) { 24765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // we're called from a different process, do the real check 24865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!checkCallingPermission( 24965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String16("android.permission.CAMERA"))) { 25065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const int uid = getCallingUid(); 25165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("Permission Denial: " 25265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian "can't use the camera pid=%d, uid=%d", pid, uid); 25365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return PERMISSION_DENIED; 25465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 25565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 25665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 25765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 25865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 25965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return BnCameraService::onTransact(code, data, reply, flags); 26065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 26165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 26265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// The reason we need this busy bit is a new CameraService::connect() request 26365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// may come in while the previous Client's destructor has not been run or is 26465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// still running. If the last strong reference of the previous Client is gone 26565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// but the destructor has not been finished, we should not allow the new Client 26665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// to be created because we need to wait for the previous Client to tear down 26765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// the hardware first. 26865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::setCameraBusy(int cameraId) { 26965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian android_atomic_write(1, &mBusy[cameraId]); 27065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 27165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 27265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::setCameraFree(int cameraId) { 27365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian android_atomic_write(0, &mBusy[cameraId]); 27465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 27565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 27665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// We share the media players for shutter and recording sound for all clients. 27765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// A reference count is kept to determine when we will actually release the 27865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// media players. 27965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 28065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic MediaPlayer* newMediaPlayer(const char *file) { 28165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian MediaPlayer* mp = new MediaPlayer(); 28265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mp->setDataSource(file, NULL) == NO_ERROR) { 283fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE); 28465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mp->prepare(); 28565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 28665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("Failed to load CameraService sounds: %s", file); 28765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NULL; 28865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 28965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mp; 29065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 29165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 29265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::loadSound() { 29365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mSoundLock); 29465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("CameraService::loadSound ref=%d", mSoundRef); 29565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mSoundRef++) return; 29665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 29765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg"); 29865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg"); 29965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 30065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 30165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::releaseSound() { 30265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mSoundLock); 30365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("CameraService::releaseSound ref=%d", mSoundRef); 30465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (--mSoundRef) return; 30565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 30665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (int i = 0; i < NUM_SOUNDS; i++) { 30765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mSoundPlayer[i] != 0) { 30865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mSoundPlayer[i]->disconnect(); 30965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mSoundPlayer[i].clear(); 31065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 31165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 31265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 31365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 31465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::playSound(sound_kind kind) { 31565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("playSound(%d)", kind); 31665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mSoundLock); 31765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<MediaPlayer> player = mSoundPlayer[kind]; 31865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (player != 0) { 31965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // do not play the sound if stream volume is 0 32065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // (typically because ringer mode is silent). 32165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int index; 322fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin AudioSystem::getStreamVolumeIndex(AUDIO_STREAM_ENFORCED_AUDIBLE, &index); 32365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (index != 0) { 32465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian player->seekTo(0); 32565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian player->start(); 32665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 32765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 32865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 32965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 33065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 33165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 33265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::Client(const sp<CameraService>& cameraService, 333b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li const sp<ICameraClient>& cameraClient, 334b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li const sp<CameraHardwareInterface>& hardware, 335e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li int cameraId, int cameraFacing, int clientPid) { 33665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int callingPid = getCallingPid(); 33765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("Client::Client E (pid %d)", callingPid); 33865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 33965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraService = cameraService; 34065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraClient = cameraClient; 341b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li mHardware = hardware; 34265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraId = cameraId; 343e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li mCameraFacing = cameraFacing; 34465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClientPid = clientPid; 34565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mMsgEnabled = 0; 346bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis mSurface = 0; 347bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis mPreviewWindow = 0; 34865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->setCallbacks(notifyCallback, 34965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian dataCallback, 35065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian dataCallbackTimestamp, 35165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian (void *)cameraId); 35265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 35365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Enable zoom, error, and focus messages by default 35465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian enableMsgType(CAMERA_MSG_ERROR | 35565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian CAMERA_MSG_ZOOM | 35665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian CAMERA_MSG_FOCUS); 35765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 35865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Callback is disabled by default 3599e626526453f91999bdf3de4c2ec8e55c5d90511Iliyan Malchev mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP; 360e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT); 361b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra mPlayShutterSound = true; 36265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian cameraService->setCameraBusy(cameraId); 36365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian cameraService->loadSound(); 36465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("Client::Client X (pid %d)", callingPid); 36565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 36665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 36765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// tear down the client 36865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::~Client() { 36965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int callingPid = getCallingPid(); 37065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("Client::~Client E (pid %d, this %p)", callingPid, this); 37165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 37265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // set mClientPid to let disconnet() tear down the hardware 37365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClientPid = callingPid; 37465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian disconnect(); 37565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraService->releaseSound(); 37665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("Client::~Client X (pid %d, this %p)", callingPid, this); 37765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 37865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 37965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 38065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 38165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::checkPid() const { 38265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int callingPid = getCallingPid(); 38365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (callingPid == mClientPid) return NO_ERROR; 38465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 38565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGW("attempt to use a locked camera from a different process" 38665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian " (old pid %d, new pid %d)", mClientPid, callingPid); 38765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return EBUSY; 38865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 38965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 39065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::checkPidAndHardware() const { 39165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = checkPid(); 39265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) return result; 39365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mHardware == 0) { 39465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("attempt to use a camera after disconnect() (pid %d)", getCallingPid()); 39565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return INVALID_OPERATION; 39665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 39765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 39865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 39965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 40065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::lock() { 40165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int callingPid = getCallingPid(); 40265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("lock (pid %d)", callingPid); 40365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 40465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 40565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // lock camera to this client if the the camera is unlocked 40665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mClientPid == 0) { 40765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClientPid = callingPid; 40865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 40965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 41065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 41165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // returns NO_ERROR if the client already owns the camera, EBUSY otherwise 41265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return checkPid(); 41365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 41465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 41565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::unlock() { 41665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int callingPid = getCallingPid(); 41765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("unlock (pid %d)", callingPid); 41865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 41965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 42065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // allow anyone to use camera (after they lock the camera) 42165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = checkPid(); 42265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result == NO_ERROR) { 4234ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li if (mHardware->recordingEnabled()) { 4244ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li LOGE("Not allowed to unlock camera during recording."); 4254ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li return INVALID_OPERATION; 4264ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li } 42765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClientPid = 0; 42865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("clear mCameraClient (pid %d)", callingPid); 42965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // we need to remove the reference to ICameraClient so that when the app 43065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // goes away, the reference count goes to 0. 43165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraClient.clear(); 43265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 43365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return result; 43465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 43565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 43665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// connect a new client to the camera 43765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::connect(const sp<ICameraClient>& client) { 43865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int callingPid = getCallingPid(); 43965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("connect E (pid %d)", callingPid); 44065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 44165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 44265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mClientPid != 0 && checkPid() != NO_ERROR) { 44365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGW("Tried to connect to a locked camera (old pid %d, new pid %d)", 44465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClientPid, callingPid); 44565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return EBUSY; 44665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 44765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 44865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mCameraClient != 0 && (client->asBinder() == mCameraClient->asBinder())) { 44965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("Connect to the same client"); 45065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 45165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 45265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 4539e626526453f91999bdf3de4c2ec8e55c5d90511Iliyan Malchev mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP; 45465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mClientPid = callingPid; 45565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraClient = client; 45665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 45765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("connect X (pid %d)", callingPid); 45865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 45965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 46065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 46165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::disconnect() { 46265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int callingPid = getCallingPid(); 46365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("disconnect E (pid %d)", callingPid); 46465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 46565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 46665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (checkPid() != NO_ERROR) { 46765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGW("different client - don't disconnect"); 46865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return; 46965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 47065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 47165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mClientPid <= 0) { 47265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("camera is unlocked (mClientPid = %d), don't tear down hardware", mClientPid); 47365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return; 47465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 47565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 47665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Make sure disconnect() is done once and once only, whether it is called 47765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // from the user directly, or called by the destructor. 47865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mHardware == 0) return; 47965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 48065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("hardware teardown"); 48165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Before destroying mHardware, we must make sure it's in the 48265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // idle state. 48365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Turn off all messages. 48465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian disableMsgType(CAMERA_MSG_ALL_MSGS); 48565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->stopPreview(); 48665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->cancelPicture(); 48765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Release the hardware resources. 48865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->release(); 48903dfce9672b36c1a334959a602f909b8410bec50Mathias Agopian 4904b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis // Release the held ANativeWindow resources. 4914b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis if (mPreviewWindow != 0) { 4924b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis mPreviewWindow = 0; 4934b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis mHardware->setPreviewWindow(mPreviewWindow); 4944b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis } 49565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware.clear(); 49665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 49765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraService->removeClient(mCameraClient); 49865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraService->setCameraFree(mCameraId); 49965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 50065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("disconnect X (pid %d)", callingPid); 50165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 50265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 50365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 50465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5050ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennisstatic void disconnectWindow(const sp<ANativeWindow>& window) { 5060ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis if (window != 0) { 5070ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis status_t result = native_window_disconnect(window.get(), 5080ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis NATIVE_WINDOW_API_CAMERA); 5090ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis if (result != NO_ERROR) { 5100ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis LOGW("native_window_disconnect failed: %s (%d)", strerror(-result), 5110ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis result); 5120ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis } 5130ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis } 5140ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis} 5150ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis 5160ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennisstatus_t CameraService::Client::setPreviewWindow(const sp<IBinder>& binder, 5170ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis const sp<ANativeWindow>& window) { 51865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 51965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = checkPidAndHardware(); 52065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) return result; 52165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 52265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // return if no change in surface. 5238b1027d3f873fc15c70f8645f1856936b69241a4Mathias Agopian if (binder == mSurface) { 5240ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis return NO_ERROR; 52565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 52665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5270ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis if (window != 0) { 5280ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis result = native_window_connect(window.get(), NATIVE_WINDOW_API_CAMERA); 5290ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis if (result != NO_ERROR) { 5300ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis LOGE("native_window_connect failed: %s (%d)", strerror(-result), 5310ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis result); 5320ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis return result; 5330ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis } 53465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 535bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis 5360ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis // If preview has been already started, register preview buffers now. 53765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mHardware->previewEnabled()) { 5380ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis if (window != 0) { 5399bc7af17974f448291a44912566ec7472a0d798bMathias Agopian native_window_set_scaling_mode(window.get(), 5409bc7af17974f448291a44912566ec7472a0d798bMathias Agopian NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 5410ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis native_window_set_buffers_transform(window.get(), mOrientation); 5420ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis result = mHardware->setPreviewWindow(window); 54365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 54465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 54565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5460ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis if (result == NO_ERROR) { 5470ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis // Everything has succeeded. Disconnect the old window and remember the 5480ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis // new window. 5490ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis disconnectWindow(mPreviewWindow); 5500ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis mSurface = binder; 5510ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis mPreviewWindow = window; 5520ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis } else { 5530ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis // Something went wrong after we connected to the new window, so 5540ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis // disconnect here. 5550ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis disconnectWindow(window); 5560ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis } 5570ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis 55865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return result; 55965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 56065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 5610ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis// set the Surface that the preview will use 5620ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennisstatus_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) { 5630ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid()); 5640ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis 5650ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis sp<IBinder> binder(surface != 0 ? surface->asBinder() : 0); 5660ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis sp<ANativeWindow> window(surface); 5670ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis return setPreviewWindow(binder, window); 5680ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis} 5690ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis 570bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis// set the SurfaceTexture that the preview will use 571bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennisstatus_t CameraService::Client::setPreviewTexture( 572bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis const sp<ISurfaceTexture>& surfaceTexture) { 573bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis LOG1("setPreviewTexture(%p) (pid %d)", surfaceTexture.get(), 574bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis getCallingPid()); 575bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis 5760ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis sp<IBinder> binder; 5770ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis sp<ANativeWindow> window; 578bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis if (surfaceTexture != 0) { 5790ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis binder = surfaceTexture->asBinder(); 5800ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis window = new SurfaceTextureClient(surfaceTexture); 581bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis } 5820ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis return setPreviewWindow(binder, window); 583bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis} 584bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis 58565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// set the preview callback flag to affect how the received frames from 58665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// preview are handled. 58765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::setPreviewCallbackFlag(int callback_flag) { 58865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("setPreviewCallbackFlag(%d) (pid %d)", callback_flag, getCallingPid()); 58965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 59065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (checkPidAndHardware() != NO_ERROR) return; 59165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 59265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mPreviewCallbackFlag = callback_flag; 5939e626526453f91999bdf3de4c2ec8e55c5d90511Iliyan Malchev if (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) { 5940667de7038238c31af77865eb6d83c5ae9ca1b1eWu-cheng Li enableMsgType(CAMERA_MSG_PREVIEW_FRAME); 5950667de7038238c31af77865eb6d83c5ae9ca1b1eWu-cheng Li } else { 5960667de7038238c31af77865eb6d83c5ae9ca1b1eWu-cheng Li disableMsgType(CAMERA_MSG_PREVIEW_FRAME); 59765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 59865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 59965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 60065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// start preview mode 60165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::startPreview() { 60265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("startPreview (pid %d)", getCallingPid()); 60365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return startCameraMode(CAMERA_PREVIEW_MODE); 60465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 60565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 60665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// start recording mode 60765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::startRecording() { 60865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("startRecording (pid %d)", getCallingPid()); 60965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return startCameraMode(CAMERA_RECORDING_MODE); 61065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 61165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 61265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// start preview or recording 61365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::startCameraMode(camera_mode mode) { 61465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("startCameraMode(%d)", mode); 61565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 61665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = checkPidAndHardware(); 61765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) return result; 61865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 61965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian switch(mode) { 62065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case CAMERA_PREVIEW_MODE: 6214b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis if (mSurface == 0 && mPreviewWindow == 0) { 62265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("mSurface is not set yet."); 62365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // still able to start preview in this case. 62465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 62565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return startPreviewMode(); 62665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case CAMERA_RECORDING_MODE: 6274b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis if (mSurface == 0 && mPreviewWindow == 0) { 6284b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis LOGE("mSurface or mPreviewWindow must be set before startRecordingMode."); 62965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return INVALID_OPERATION; 63065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 63165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return startRecordingMode(); 63265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian default: 63365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return UNKNOWN_ERROR; 63465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 63565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 63665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 63765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::startPreviewMode() { 63865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("startPreviewMode"); 63965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = NO_ERROR; 64065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 64165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // if preview has been enabled, nothing needs to be done 64265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mHardware->previewEnabled()) { 64365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 64465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 64565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 64603dfce9672b36c1a334959a602f909b8410bec50Mathias Agopian if (mPreviewWindow != 0) { 6479bc7af17974f448291a44912566ec7472a0d798bMathias Agopian native_window_set_scaling_mode(mPreviewWindow.get(), 6489bc7af17974f448291a44912566ec7472a0d798bMathias Agopian NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW); 64903dfce9672b36c1a334959a602f909b8410bec50Mathias Agopian native_window_set_buffers_transform(mPreviewWindow.get(), 65003dfce9672b36c1a334959a602f909b8410bec50Mathias Agopian mOrientation); 65165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 65203dfce9672b36c1a334959a602f909b8410bec50Mathias Agopian mHardware->setPreviewWindow(mPreviewWindow); 65303dfce9672b36c1a334959a602f909b8410bec50Mathias Agopian result = mHardware->startPreview(); 65403dfce9672b36c1a334959a602f909b8410bec50Mathias Agopian 65565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return result; 65665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 65765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 65865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::startRecordingMode() { 65965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("startRecordingMode"); 66065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = NO_ERROR; 66165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 66265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // if recording has been enabled, nothing needs to be done 66365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mHardware->recordingEnabled()) { 66465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 66565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 66665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 66765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // if preview has not been started, start preview first 66865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!mHardware->previewEnabled()) { 66965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result = startPreviewMode(); 67065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) { 67165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return result; 67265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 67365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 67465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 67565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // start recording mode 67665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian enableMsgType(CAMERA_MSG_VIDEO_FRAME); 67765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraService->playSound(SOUND_RECORDING); 67865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result = mHardware->startRecording(); 67965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) { 68065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("mHardware->startRecording() failed with status %d", result); 68165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 68265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return result; 68365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 68465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 68565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// stop preview mode 68665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::stopPreview() { 68765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("stopPreview (pid %d)", getCallingPid()); 68865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 68965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (checkPidAndHardware() != NO_ERROR) return; 69065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 6914b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis 69265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian disableMsgType(CAMERA_MSG_PREVIEW_FRAME); 69365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->stopPreview(); 69465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 69565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mPreviewBuffer.clear(); 69665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 69765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 69865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// stop recording mode 69965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::stopRecording() { 70065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("stopRecording (pid %d)", getCallingPid()); 70165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 70265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (checkPidAndHardware() != NO_ERROR) return; 70365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 70465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mCameraService->playSound(SOUND_RECORDING); 70565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian disableMsgType(CAMERA_MSG_VIDEO_FRAME); 70665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->stopRecording(); 70765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 70865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mPreviewBuffer.clear(); 70965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 71065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 71165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// release a recording frame 71265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::releaseRecordingFrame(const sp<IMemory>& mem) { 71365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 71465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (checkPidAndHardware() != NO_ERROR) return; 71565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->releaseRecordingFrame(mem); 71665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 71765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 718e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dongstatus_t CameraService::Client::storeMetaDataInBuffers(bool enabled) 719e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dong{ 720e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dong LOG1("storeMetaDataInBuffers: %s", enabled? "true": "false"); 721e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dong Mutex::Autolock lock(mLock); 722e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dong if (checkPidAndHardware() != NO_ERROR) { 723e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dong return UNKNOWN_ERROR; 724e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dong } 725e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dong return mHardware->storeMetaDataInBuffers(enabled); 726e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dong} 727e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dong 72865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool CameraService::Client::previewEnabled() { 72965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("previewEnabled (pid %d)", getCallingPid()); 73065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 73165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 73265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (checkPidAndHardware() != NO_ERROR) return false; 73365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mHardware->previewEnabled(); 73465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 73565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 73665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool CameraService::Client::recordingEnabled() { 73765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("recordingEnabled (pid %d)", getCallingPid()); 73865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 73965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 74065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (checkPidAndHardware() != NO_ERROR) return false; 74165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mHardware->recordingEnabled(); 74265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 74365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 74465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::autoFocus() { 74565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("autoFocus (pid %d)", getCallingPid()); 74665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 74765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 74865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = checkPidAndHardware(); 74965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) return result; 75065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 75165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mHardware->autoFocus(); 75265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 75365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 75465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::cancelAutoFocus() { 75565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("cancelAutoFocus (pid %d)", getCallingPid()); 75665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 75765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 75865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = checkPidAndHardware(); 75965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) return result; 76065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 76165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mHardware->cancelAutoFocus(); 76265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 76365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 76465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// take a picture - image is returned in callback 765e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dongstatus_t CameraService::Client::takePicture(int msgType) { 766e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong LOG1("takePicture (pid %d): 0x%x", getCallingPid(), msgType); 76765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 76865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 76965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = checkPidAndHardware(); 77065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) return result; 77165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 7724ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li if (mHardware->recordingEnabled()) { 7734ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li LOGE("Cannot take picture during recording."); 7744ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li return INVALID_OPERATION; 7754ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li } 7764ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li 777e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong if ((msgType & CAMERA_MSG_RAW_IMAGE) && 778e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong (msgType & CAMERA_MSG_RAW_IMAGE_NOTIFY)) { 779e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong LOGE("CAMERA_MSG_RAW_IMAGE and CAMERA_MSG_RAW_IMAGE_NOTIFY" 780e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong " cannot be both enabled"); 781e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong return BAD_VALUE; 782e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong } 783e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong 784e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong // We only accept picture related message types 785e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong // and ignore other types of messages for takePicture(). 786e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong int picMsgType = msgType 787e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong & (CAMERA_MSG_SHUTTER | 788e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong CAMERA_MSG_POSTVIEW_FRAME | 789e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong CAMERA_MSG_RAW_IMAGE | 790e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong CAMERA_MSG_RAW_IMAGE_NOTIFY | 791e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong CAMERA_MSG_COMPRESSED_IMAGE); 792e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong 793e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong enableMsgType(picMsgType); 79465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 79565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mHardware->takePicture(); 79665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 79765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 79865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// set preview/capture parameters - key/value pairs 79965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::setParameters(const String8& params) { 80065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("setParameters (pid %d) (%s)", getCallingPid(), params.string()); 80165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 80265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 80365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = checkPidAndHardware(); 80465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) return result; 80565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 80665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian CameraParameters p(params); 80765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mHardware->setParameters(p); 80865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 80965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 81065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// get preview/capture parameters - key/value pairs 81165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianString8 CameraService::Client::getParameters() const { 81265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 81365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (checkPidAndHardware() != NO_ERROR) return String8(); 81465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 81565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 params(mHardware->getParameters().flatten()); 81665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("getParameters (pid %d) (%s)", getCallingPid(), params.string()); 81765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return params; 81865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 81965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 820b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra// enable shutter sound 821b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatrastatus_t CameraService::Client::enableShutterSound(bool enable) { 822b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra LOG1("enableShutterSound (pid %d)", getCallingPid()); 823b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra 824b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra status_t result = checkPidAndHardware(); 825b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra if (result != NO_ERROR) return result; 826b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra 827b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra if (enable) { 828b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra mPlayShutterSound = true; 829b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra return OK; 830b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra } 831b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra 832b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra // Disabling shutter sound may not be allowed. In that case only 833b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra // allow the mediaserver process to disable the sound. 834b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra char value[PROPERTY_VALUE_MAX]; 835b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra property_get("ro.camera.sound.forced", value, "0"); 836b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra if (strcmp(value, "0") != 0) { 837b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra // Disabling shutter sound is not allowed. Deny if the current 838b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra // process is not mediaserver. 839b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra if (getCallingPid() != getpid()) { 840b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra LOGE("Failed to disable shutter sound. Permission denied (pid %d)", getCallingPid()); 841b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra return PERMISSION_DENIED; 842b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra } 843b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra } 844b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra 845b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra mPlayShutterSound = false; 846b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra return OK; 847b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra} 848b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra 84965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) { 85065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("sendCommand (pid %d)", getCallingPid()); 8514a73f3da3501db6e95473a4a653d6319c6d618e2Wu-cheng Li int orientation; 85265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian Mutex::Autolock lock(mLock); 85365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian status_t result = checkPidAndHardware(); 85465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (result != NO_ERROR) return result; 85565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 85665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) { 85765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // The orientation cannot be set during preview. 85865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mHardware->previewEnabled()) { 85965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return INVALID_OPERATION; 86065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 861e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li // Mirror the preview if the camera is front-facing. 862e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li orientation = getOrientation(arg1, mCameraFacing == CAMERA_FACING_FRONT); 863e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li if (orientation == -1) return BAD_VALUE; 864e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li 8654a73f3da3501db6e95473a4a653d6319c6d618e2Wu-cheng Li if (mOrientation != orientation) { 8664a73f3da3501db6e95473a4a653d6319c6d618e2Wu-cheng Li mOrientation = orientation; 8674a73f3da3501db6e95473a4a653d6319c6d618e2Wu-cheng Li } 86865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return OK; 869b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra } else if (cmd == CAMERA_CMD_ENABLE_SHUTTER_SOUND) { 870b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra switch (arg1) { 871b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra case 0: 872b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra enableShutterSound(false); 873b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra break; 874b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra case 1: 875b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra enableShutterSound(true); 876b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra break; 877b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra default: 878b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra return BAD_VALUE; 879b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra } 880b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra return OK; 8813b7b358d1a45844ca427626554ff81f472fd1583Nipun Kwatra } else if (cmd == CAMERA_CMD_PLAY_RECORDING_SOUND) { 8823b7b358d1a45844ca427626554ff81f472fd1583Nipun Kwatra mCameraService->playSound(SOUND_RECORDING); 88365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 88465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 88565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return mHardware->sendCommand(cmd, arg1, arg2); 88665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 88765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 88865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 88965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 89065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::enableMsgType(int32_t msgType) { 89165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian android_atomic_or(msgType, &mMsgEnabled); 89265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->enableMsgType(msgType); 89365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 89465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 89565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::disableMsgType(int32_t msgType) { 89665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian android_atomic_and(~msgType, &mMsgEnabled); 89765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mHardware->disableMsgType(msgType); 89865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 89965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 90065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define CHECK_MESSAGE_INTERVAL 10 // 10ms 90165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool CameraService::Client::lockIfMessageWanted(int32_t msgType) { 90265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int sleepCount = 0; 90365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian while (mMsgEnabled & msgType) { 90465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mLock.tryLock() == NO_ERROR) { 90565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (sleepCount > 0) { 90665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("lockIfMessageWanted(%d): waited for %d ms", 90765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian msgType, sleepCount * CHECK_MESSAGE_INTERVAL); 90865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 90965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return true; 91065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 91165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (sleepCount++ == 0) { 91265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG1("lockIfMessageWanted(%d): enter sleep", msgType); 91365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 91465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian usleep(CHECK_MESSAGE_INTERVAL * 1000); 91565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 91665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGW("lockIfMessageWanted(%d): dropped unwanted message", msgType); 91765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return false; 91865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 91965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 92065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 92165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 92265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Converts from a raw pointer to the client to a strong pointer during a 92365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// hardware callback. This requires the callbacks only happen when the client 92465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// is still alive. 92565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<CameraService::Client> CameraService::Client::getClientFromCookie(void* user) { 92665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<Client> client = gCameraService->getClientById((int) user); 92765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 92865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // This could happen if the Client is in the process of shutting down (the 92965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // last strong reference is gone, but the destructor hasn't finished 93065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // stopping the hardware). 93165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (client == 0) return NULL; 93265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 93365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // The checks below are not necessary and are for debugging only. 93465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (client->mCameraService.get() != gCameraService) { 93565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("mismatch service!"); 93665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NULL; 93765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 93865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 93965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (client->mHardware == 0) { 94065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("mHardware == 0: callback after disconnect()?"); 94165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NULL; 94265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 94365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 94465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return client; 94565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 94665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 94765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Callback messages can be dispatched to internal handlers or pass to our 94865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// client's callback functions, depending on the message type. 94965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// 95065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// notifyCallback: 95165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// CAMERA_MSG_SHUTTER handleShutter 95265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// (others) c->notifyCallback 95365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// dataCallback: 95465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// CAMERA_MSG_PREVIEW_FRAME handlePreviewData 95565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// CAMERA_MSG_POSTVIEW_FRAME handlePostview 95665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// CAMERA_MSG_RAW_IMAGE handleRawPicture 95765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// CAMERA_MSG_COMPRESSED_IMAGE handleCompressedPicture 95865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// (others) c->dataCallback 95965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// dataCallbackTimestamp 96065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// (others) c->dataCallbackTimestamp 96165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// 96265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// NOTE: the *Callback functions grab mLock of the client before passing 96365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// control to handle* functions. So the handle* functions must release the 96465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// lock before calling the ICameraClient's callbacks, so those callbacks can 96565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// invoke methods in the Client class again (For example, the preview frame 96665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// callback may want to releaseRecordingFrame). The handle* functions must 96765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// release the lock after all accesses to member variables, so it must be 96865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// handled very carefully. 96965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 97065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::notifyCallback(int32_t msgType, int32_t ext1, 97165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t ext2, void* user) { 97265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG2("notifyCallback(%d)", msgType); 97365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 97465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<Client> client = getClientFromCookie(user); 97565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (client == 0) return; 97665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!client->lockIfMessageWanted(msgType)) return; 97765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 97865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian switch (msgType) { 97965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case CAMERA_MSG_SHUTTER: 98065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // ext1 is the dimension of the yuv picture. 981108dddf924d714c811dd565b8f4c7a0178cca2f2Iliyan Malchev client->handleShutter(); 98265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 98365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian default: 98465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->handleGenericNotify(msgType, ext1, ext2); 98565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 98665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 98765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 98865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 98965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::dataCallback(int32_t msgType, 99065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const sp<IMemory>& dataPtr, void* user) { 99165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG2("dataCallback(%d)", msgType); 99265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 99365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<Client> client = getClientFromCookie(user); 99465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (client == 0) return; 99565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!client->lockIfMessageWanted(msgType)) return; 99665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 99765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (dataPtr == 0) { 99865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("Null data returned in data callback"); 99965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); 100065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return; 100165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 100265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 100365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian switch (msgType) { 100465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case CAMERA_MSG_PREVIEW_FRAME: 100565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->handlePreviewData(dataPtr); 100665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 100765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case CAMERA_MSG_POSTVIEW_FRAME: 100865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->handlePostview(dataPtr); 100965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 101065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case CAMERA_MSG_RAW_IMAGE: 101165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->handleRawPicture(dataPtr); 101265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 101365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian case CAMERA_MSG_COMPRESSED_IMAGE: 101465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->handleCompressedPicture(dataPtr); 101565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 101665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian default: 101765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->handleGenericData(msgType, dataPtr); 101865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 101965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 102065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 102165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 102265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::dataCallbackTimestamp(nsecs_t timestamp, 102365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t msgType, const sp<IMemory>& dataPtr, void* user) { 102465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG2("dataCallbackTimestamp(%d)", msgType); 102565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 102665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<Client> client = getClientFromCookie(user); 102765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (client == 0) return; 1028986ef2ad4c96952711d87af481f3afb40aa10775James Dong if (!client->lockIfMessageWanted(msgType)) return; 102965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 103065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (dataPtr == 0) { 103165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("Null data returned in data with timestamp callback"); 103265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); 103365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return; 103465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 103565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 103665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->handleGenericDataTimestamp(timestamp, msgType, dataPtr); 103765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 103865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 103965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// snapshot taken callback 1040108dddf924d714c811dd565b8f4c7a0178cca2f2Iliyan Malchevvoid CameraService::Client::handleShutter(void) { 1041b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra if (mPlayShutterSound) { 1042b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra mCameraService->playSound(SOUND_SHUTTER); 1043b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra } 104465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 104565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<ICameraClient> c = mCameraClient; 104665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (c != 0) { 104765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 104865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0); 104965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!lockIfMessageWanted(CAMERA_MSG_SHUTTER)) return; 105065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 105165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian disableMsgType(CAMERA_MSG_SHUTTER); 105265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 105365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 105465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 105565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 105665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// preview callback - frame buffer update 105765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handlePreviewData(const sp<IMemory>& mem) { 105865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian ssize_t offset; 105965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian size_t size; 106065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); 106165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 106265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // local copy of the callback flags 106365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int flags = mPreviewCallbackFlag; 106465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 106565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // is callback enabled? 10669e626526453f91999bdf3de4c2ec8e55c5d90511Iliyan Malchev if (!(flags & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK)) { 106765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // If the enable bit is off, the copy-out and one-shot bits are ignored 106865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG2("frame callback is disabled"); 106965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 107065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return; 107165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 107265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 107365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // hold a strong pointer to the client 107465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<ICameraClient> c = mCameraClient; 107565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 107665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // clear callback flags if no client or one-shot mode 10779e626526453f91999bdf3de4c2ec8e55c5d90511Iliyan Malchev if (c == 0 || (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) { 107865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG2("Disable preview callback"); 10799e626526453f91999bdf3de4c2ec8e55c5d90511Iliyan Malchev mPreviewCallbackFlag &= ~(CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK | 10809e626526453f91999bdf3de4c2ec8e55c5d90511Iliyan Malchev CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK | 10819e626526453f91999bdf3de4c2ec8e55c5d90511Iliyan Malchev CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK); 10820667de7038238c31af77865eb6d83c5ae9ca1b1eWu-cheng Li disableMsgType(CAMERA_MSG_PREVIEW_FRAME); 108365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 108465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 108565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (c != 0) { 108665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // Is the received frame copied out or not? 10879e626526453f91999bdf3de4c2ec8e55c5d90511Iliyan Malchev if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) { 108865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG2("frame is copied"); 108965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian copyFrameAndPostCopiedFrame(c, heap, offset, size); 109065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 109165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG2("frame is forwarded"); 109265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 109365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian c->dataCallback(CAMERA_MSG_PREVIEW_FRAME, mem); 109465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 109565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 109665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 109765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 109865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 109965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 110065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// picture callback - postview image ready 110165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handlePostview(const sp<IMemory>& mem) { 110265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian disableMsgType(CAMERA_MSG_POSTVIEW_FRAME); 110365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 110465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<ICameraClient> c = mCameraClient; 110565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 110665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (c != 0) { 110765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem); 110865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 110965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 111065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 111165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// picture callback - raw image ready 111265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handleRawPicture(const sp<IMemory>& mem) { 111365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian disableMsgType(CAMERA_MSG_RAW_IMAGE); 111465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 111565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian ssize_t offset; 111665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian size_t size; 111765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); 111865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 111965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<ICameraClient> c = mCameraClient; 112065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 112165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (c != 0) { 112265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem); 112365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 112465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 112565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 112665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// picture callback - compressed picture ready 112765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handleCompressedPicture(const sp<IMemory>& mem) { 112865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE); 112965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 113065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<ICameraClient> c = mCameraClient; 113165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 113265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (c != 0) { 113365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem); 113465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 113565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 113665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 113765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 113865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handleGenericNotify(int32_t msgType, 113965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t ext1, int32_t ext2) { 114065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<ICameraClient> c = mCameraClient; 114165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 114265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (c != 0) { 114365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian c->notifyCallback(msgType, ext1, ext2); 114465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 114565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 114665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 114765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handleGenericData(int32_t msgType, 114865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const sp<IMemory>& dataPtr) { 114965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<ICameraClient> c = mCameraClient; 115065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 115165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (c != 0) { 115265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian c->dataCallback(msgType, dataPtr); 115365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 115465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 115565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 115665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handleGenericDataTimestamp(nsecs_t timestamp, 115765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int32_t msgType, const sp<IMemory>& dataPtr) { 115865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<ICameraClient> c = mCameraClient; 115965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 116065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (c != 0) { 116165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian c->dataCallbackTimestamp(timestamp, msgType, dataPtr); 116265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 116365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 116465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 116565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::copyFrameAndPostCopiedFrame( 116665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const sp<ICameraClient>& client, const sp<IMemoryHeap>& heap, 116765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian size_t offset, size_t size) { 116865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOG2("copyFrameAndPostCopiedFrame"); 116965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // It is necessary to copy out of pmem before sending this to 117065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // the callback. For efficiency, reuse the same MemoryHeapBase 117165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // provided it's big enough. Don't allocate the memory or 117265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // perform the copy if there's no callback. 117365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // hold the preview lock while we grab a reference to the preview buffer 117465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<MemoryHeapBase> previewBuffer; 117565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 117665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mPreviewBuffer == 0) { 117765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mPreviewBuffer = new MemoryHeapBase(size, 0, NULL); 117865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else if (size > mPreviewBuffer->virtualSize()) { 117965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mPreviewBuffer.clear(); 118065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mPreviewBuffer = new MemoryHeapBase(size, 0, NULL); 118165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 118265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mPreviewBuffer == 0) { 118365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("failed to allocate space for preview buffer"); 118465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 118565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return; 118665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 118765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian previewBuffer = mPreviewBuffer; 118865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 118965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian memcpy(previewBuffer->base(), (uint8_t *)heap->base() + offset, size); 119065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 119165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size); 119265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (frame == 0) { 119365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian LOGE("failed to allocate space for frame callback"); 119465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 119565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return; 119665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 119765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 119865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian mLock.unlock(); 119965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->dataCallback(CAMERA_MSG_PREVIEW_FRAME, frame); 120065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 120165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 1202e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Liint CameraService::Client::getOrientation(int degrees, bool mirror) { 1203e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li if (!mirror) { 1204e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li if (degrees == 0) return 0; 1205e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li else if (degrees == 90) return HAL_TRANSFORM_ROT_90; 1206e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li else if (degrees == 180) return HAL_TRANSFORM_ROT_180; 1207e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li else if (degrees == 270) return HAL_TRANSFORM_ROT_270; 1208e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li } else { // Do mirror (horizontal flip) 1209e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li if (degrees == 0) { // FLIP_H and ROT_0 1210e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li return HAL_TRANSFORM_FLIP_H; 1211e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li } else if (degrees == 90) { // FLIP_H and ROT_90 1212e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90; 1213e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li } else if (degrees == 180) { // FLIP_H and ROT_180 1214e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li return HAL_TRANSFORM_FLIP_V; 1215e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li } else if (degrees == 270) { // FLIP_H and ROT_270 1216e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90; 1217e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li } 1218e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li } 1219e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li LOGE("Invalid setDisplayOrientation degrees=%d", degrees); 1220e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li return -1; 1221e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li} 1222e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li 1223e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li 122465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ---------------------------------------------------------------------------- 122565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 122665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50; 122765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockSleep = 60000; 122865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 122965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic bool tryLock(Mutex& mutex) 123065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{ 123165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian bool locked = false; 123265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (int i = 0; i < kDumpLockRetries; ++i) { 123365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (mutex.tryLock() == NO_ERROR) { 123465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian locked = true; 123565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian break; 123665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 123765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian usleep(kDumpLockSleep); 123865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 123965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return locked; 124065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 124165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 124265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::dump(int fd, const Vector<String16>& args) { 124365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian static const char* kDeadlockedString = "CameraService may be deadlocked\n"; 124465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 124565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian const size_t SIZE = 256; 124665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian char buffer[SIZE]; 124765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result; 124865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (checkCallingPermission(String16("android.permission.DUMP")) == false) { 124965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian snprintf(buffer, SIZE, "Permission Denial: " 125065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian "can't dump CameraService from pid=%d, uid=%d\n", 125165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian getCallingPid(), 125265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian getCallingUid()); 125365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 125465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 125565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } else { 125665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian bool locked = tryLock(mServiceLock); 125765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // failed to lock - CameraService is probably deadlocked 125865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!locked) { 125965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 result(kDeadlockedString); 126065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 126165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 126265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 126365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian bool hasClient = false; 126465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (int i = 0; i < mNumberOfCameras; i++) { 126565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sp<Client> client = mClient[i].promote(); 126665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (client == 0) continue; 126765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian hasClient = true; 126865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sprintf(buffer, "Client[%d] (%p) PID: %d\n", 126965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian i, 127065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->getCameraClient()->asBinder().get(), 127165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->mClientPid); 127265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 127365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 127465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian client->mHardware->dump(fd, args); 127565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 127665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (!hasClient) { 127765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append("No camera client yet.\n"); 127865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian write(fd, result.string(), result.size()); 127965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 128065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 128165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (locked) mServiceLock.unlock(); 128265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 128365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian // change logging level 128465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int n = args.size(); 128565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian for (int i = 0; i + 1 < n; i++) { 128665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian if (args[i] == String16("-v")) { 128765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian String8 levelStr(args[i+1]); 128865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian int level = atoi(levelStr.string()); 128965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian sprintf(buffer, "Set Log Level to %d", level); 129065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian result.append(buffer); 129165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian setLogLevel(level); 129265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 129365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 129465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian } 129565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian return NO_ERROR; 129665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian} 129765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian 129865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android 1299