CameraService.cpp revision df712ea86e6350f7005a02ab0e1c60c28a343ed0
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>
32df712ea86e6350f7005a02ab0e1c60c28a343ed0Mathias Agopian#include <gui/Surface.h>
3365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <hardware/hardware.h>
3465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/AudioSystem.h>
3565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <media/mediaplayer.h>
3665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Errors.h>
3765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/Log.h>
3865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include <utils/String16.h>
3965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#include "CameraService.h"
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
50b8a805261bf0282e992d3608035e47d05a898710Steve Block#define LOG1(...) ALOGD_IF(gLogLevel >= 1, __VA_ARGS__);
51b8a805261bf0282e992d3608035e47d05a898710Steve Block#define LOG2(...) ALOGD_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{
76df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block    ALOGI("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) {
8629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("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) {
9229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("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]) {
10529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("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();
1365861a9a98c641261c4807c976c750e4611b3a57dTyler Luu    sp<CameraHardwareInterface> hardware = NULL;
1375861a9a98c641261c4807c976c750e4611b3a57dTyler Luu
13865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId);
13965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1408951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    if (!mModule) {
14129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Camera HAL module not loaded");
1428951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev        return NULL;
1438951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    }
1448951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
14565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<Client> client;
14665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cameraId < 0 || cameraId >= mNumberOfCameras) {
14729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).",
14865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            callingPid, cameraId);
14965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NULL;
15065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
15165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
152a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    char value[PROPERTY_VALUE_MAX];
153a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    property_get("sys.secpolicy.camera.disabled", value, "0");
154a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    if (strcmp(value, "1") == 0) {
155a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li        // Camera is disabled by DevicePolicyManager.
156df64d15042bbd5e0e4933ac49bf3c177dd94752cSteve Block        ALOGI("Camera is disabled. connect X (pid %d) rejected", callingPid);
157a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li        return NULL;
158a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li    }
159a3355430a36bbfa7b2c0d90eb30834f1c5dac337Wu-cheng Li
16065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mServiceLock);
16165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mClient[cameraId] != 0) {
16265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        client = mClient[cameraId].promote();
16365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (client != 0) {
16465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
16565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                LOG1("CameraService::connect X (pid %d) (the same client)",
16665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    callingPid);
16765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                return client;
16865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            } else {
1695ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block                ALOGW("CameraService::connect X (pid %d) rejected (existing client).",
17065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    callingPid);
17165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                return NULL;
17265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
17365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
17465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mClient[cameraId].clear();
17565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
17665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
17765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mBusy[cameraId]) {
1785ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("CameraService::connect X (pid %d) rejected"
17965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian             " (camera %d is still busy).", callingPid, cameraId);
18065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NULL;
18165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
18265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1838951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    struct camera_info info;
1848951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    if (mModule->get_camera_info(cameraId, &info) != OK) {
18529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Invalid camera id %d", cameraId);
186b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li        return NULL;
187b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li    }
1888951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
1898951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    char camera_device_name[10];
1908951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev    snprintf(camera_device_name, sizeof(camera_device_name), "%d", cameraId);
1918951a97b1f8462c37e740ea5082eea0445d2c501Iliyan Malchev
1925861a9a98c641261c4807c976c750e4611b3a57dTyler Luu    hardware = new CameraHardwareInterface(camera_device_name);
1935861a9a98c641261c4807c976c750e4611b3a57dTyler Luu    if (hardware->initialize(&mModule->common) != OK) {
1945861a9a98c641261c4807c976c750e4611b3a57dTyler Luu        hardware.clear();
1955861a9a98c641261c4807c976c750e4611b3a57dTyler Luu        return NULL;
1965861a9a98c641261c4807c976c750e4611b3a57dTyler Luu    }
1975861a9a98c641261c4807c976c750e4611b3a57dTyler Luu
1985861a9a98c641261c4807c976c750e4611b3a57dTyler Luu    client = new Client(this, cameraClient, hardware, cameraId, info.facing, callingPid);
19965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mClient[cameraId] = client;
20065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::connect X");
20165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return client;
20265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
20365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
20465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::removeClient(const sp<ICameraClient>& cameraClient) {
20565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
20665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::removeClient E (pid %d)", callingPid);
20765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
20865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < mNumberOfCameras; i++) {
20965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Declare this before the lock to make absolutely sure the
21065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // destructor won't be called with the lock held.
21165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        sp<Client> client;
21265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
21365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        Mutex::Autolock lock(mServiceLock);
21465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
21565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // This happens when we have already disconnected (or this is
21665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // just another unused camera).
21765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mClient[i] == 0) continue;
21865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
21965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Promote mClient. It can fail if we are called from this path:
22065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Client::~Client() -> disconnect() -> removeClient().
22165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        client = mClient[i].promote();
22265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
22365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (client == 0) {
22465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mClient[i].clear();
22565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            continue;
22665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
22765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
22865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
22965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // Found our camera, clear and leave.
23065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            LOG1("removeClient: clear camera %d", i);
23165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mClient[i].clear();
23265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
23365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
23465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
23565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
23665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::removeClient X (pid %d)", callingPid);
23765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
23865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
23965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<CameraService::Client> CameraService::getClientById(int cameraId) {
24065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cameraId < 0 || cameraId >= mNumberOfCameras) return NULL;
24165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mClient[cameraId].promote();
24265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
24365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
24465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::onTransact(
24565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
24665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Permission checks
24765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (code) {
24865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case BnCameraService::CONNECT:
24965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            const int pid = getCallingPid();
25065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            const int self_pid = getpid();
25165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (pid != self_pid) {
25265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // we're called from a different process, do the real check
25365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                if (!checkCallingPermission(
25465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                        String16("android.permission.CAMERA"))) {
25565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    const int uid = getCallingUid();
25629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                    ALOGE("Permission Denial: "
25765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                         "can't use the camera pid=%d, uid=%d", pid, uid);
25865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    return PERMISSION_DENIED;
25965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                }
26065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
26165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
26265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
26365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
26465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return BnCameraService::onTransact(code, data, reply, flags);
26565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
26665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
26765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// The reason we need this busy bit is a new CameraService::connect() request
26865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// may come in while the previous Client's destructor has not been run or is
26965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// still running. If the last strong reference of the previous Client is gone
27065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// but the destructor has not been finished, we should not allow the new Client
27165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// to be created because we need to wait for the previous Client to tear down
27265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// the hardware first.
27365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::setCameraBusy(int cameraId) {
27465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(1, &mBusy[cameraId]);
27565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
27665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
27765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::setCameraFree(int cameraId) {
27865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_write(0, &mBusy[cameraId]);
27965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
28065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
28165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// We share the media players for shutter and recording sound for all clients.
28265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// A reference count is kept to determine when we will actually release the
28365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// media players.
28465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
285ff4f55c8d77e276dbcceedb4e560ca1d91ba38baChih-Chung ChangMediaPlayer* CameraService::newMediaPlayer(const char *file) {
28665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    MediaPlayer* mp = new MediaPlayer();
28765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mp->setDataSource(file, NULL) == NO_ERROR) {
28860a78ac9535878984b0777788760b9ee7465c5e6Eino-Ville Talvala        mp->setAudioStreamType(AUDIO_STREAM_ENFORCED_AUDIBLE);
28965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mp->prepare();
29065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
29129357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Failed to load CameraService sounds: %s", file);
29265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NULL;
29365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
29465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mp;
29565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
29665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
29765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::loadSound() {
29865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
29965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::loadSound ref=%d", mSoundRef);
30065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mSoundRef++) return;
30165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
30265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mSoundPlayer[SOUND_SHUTTER] = newMediaPlayer("/system/media/audio/ui/camera_click.ogg");
30365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mSoundPlayer[SOUND_RECORDING] = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg");
30465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
30565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
30665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::releaseSound() {
30765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
30865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("CameraService::releaseSound ref=%d", mSoundRef);
30965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (--mSoundRef) return;
31065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < NUM_SOUNDS; i++) {
31265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mSoundPlayer[i] != 0) {
31365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSoundPlayer[i]->disconnect();
31465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mSoundPlayer[i].clear();
31565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
31665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
31765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
31865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
31965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::playSound(sound_kind kind) {
32065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("playSound(%d)", kind);
32165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mSoundLock);
32265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<MediaPlayer> player = mSoundPlayer[kind];
32365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (player != 0) {
3248888a75f01d904541e409e858d23e4150ace34b6Chih-Chung Chang        player->seekTo(0);
3258888a75f01d904541e409e858d23e4150ace34b6Chih-Chung Chang        player->start();
32665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
32765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
32865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
32965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
33065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::Client(const sp<CameraService>& cameraService,
332b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li        const sp<ICameraClient>& cameraClient,
333b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li        const sp<CameraHardwareInterface>& hardware,
334e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li        int cameraId, int cameraFacing, int clientPid) {
33565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
33665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("Client::Client E (pid %d)", callingPid);
33765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
33865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraService = cameraService;
33965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraClient = cameraClient;
340b7a67942823e8339eb298238f117aaa6d7b63111Wu-cheng Li    mHardware = hardware;
34165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraId = cameraId;
342e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li    mCameraFacing = cameraFacing;
34365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mClientPid = clientPid;
34465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mMsgEnabled = 0;
345bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis    mSurface = 0;
346bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis    mPreviewWindow = 0;
34765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardware->setCallbacks(notifyCallback,
34865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            dataCallback,
34965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            dataCallbackTimestamp,
35065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                            (void *)cameraId);
35165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
35257c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li    // Enable zoom, error, focus, and metadata messages by default
35357c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li    enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |
354d620506220a15177942a8168d09c517740e908d0Wu-cheng Li                  CAMERA_MSG_PREVIEW_METADATA | CAMERA_MSG_FOCUS_MOVE);
35565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
35665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Callback is disabled by default
3579e626526453f91999bdf3de4c2ec8e55c5d90511Iliyan Malchev    mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
358e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li    mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT);
359b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra    mPlayShutterSound = true;
36065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cameraService->setCameraBusy(cameraId);
36165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    cameraService->loadSound();
36265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("Client::Client X (pid %d)", callingPid);
36365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
36465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
36565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// tear down the client
36665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianCameraService::Client::~Client() {
36765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
36865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("Client::~Client E (pid %d, this %p)", callingPid, this);
36965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // set mClientPid to let disconnet() tear down the hardware
37165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mClientPid = callingPid;
37265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    disconnect();
37365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraService->releaseSound();
37465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("Client::~Client X (pid %d, this %p)", callingPid, this);
37565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
37665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
37865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
37965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::checkPid() const {
38065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
38165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (callingPid == mClientPid) return NO_ERROR;
38265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
3835ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block    ALOGW("attempt to use a locked camera from a different process"
38465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian         " (old pid %d, new pid %d)", mClientPid, callingPid);
38565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return EBUSY;
38665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
38765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
38865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::checkPidAndHardware() const {
38965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t result = checkPid();
39065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (result != NO_ERROR) return result;
39165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mHardware == 0) {
39229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("attempt to use a camera after disconnect() (pid %d)", getCallingPid());
39365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return INVALID_OPERATION;
39465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
39565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
39665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
39765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
39865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::lock() {
39965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
40065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("lock (pid %d)", callingPid);
40165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mLock);
40265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
40365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // lock camera to this client if the the camera is unlocked
40465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mClientPid == 0) {
40565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mClientPid = callingPid;
40665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_ERROR;
40765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
40865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
40965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // returns NO_ERROR if the client already owns the camera, EBUSY otherwise
41065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return checkPid();
41165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
41265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
41365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::unlock() {
41465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
41565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("unlock (pid %d)", callingPid);
41665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mLock);
41765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
41865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // allow anyone to use camera (after they lock the camera)
41965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t result = checkPid();
42065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (result == NO_ERROR) {
4214ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        if (mHardware->recordingEnabled()) {
42229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Not allowed to unlock camera during recording.");
4234ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li            return INVALID_OPERATION;
4244ca2c7c913f8bd4ada13aca56d36045d42d1e00fWu-cheng Li        }
42565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mClientPid = 0;
42665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        LOG1("clear mCameraClient (pid %d)", callingPid);
42765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // we need to remove the reference to ICameraClient so that when the app
42865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // goes away, the reference count goes to 0.
42965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mCameraClient.clear();
43065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
43165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return result;
43265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
43365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
43465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// connect a new client to the camera
43565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::connect(const sp<ICameraClient>& client) {
43665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
43765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("connect E (pid %d)", callingPid);
43865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mLock);
43965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
44065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mClientPid != 0 && checkPid() != NO_ERROR) {
4415ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("Tried to connect to a locked camera (old pid %d, new pid %d)",
44265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                mClientPid, callingPid);
44365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return EBUSY;
44465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
44565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
44665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mCameraClient != 0 && (client->asBinder() == mCameraClient->asBinder())) {
44765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        LOG1("Connect to the same client");
44865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_ERROR;
44965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
45065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4519e626526453f91999bdf3de4c2ec8e55c5d90511Iliyan Malchev    mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP;
45265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mClientPid = callingPid;
45365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraClient = client;
45465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
45565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("connect X (pid %d)", callingPid);
45665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
45765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
45865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
4597574da5a501fc9289fee49fdaf1fdb9d47dae2b6Wu-cheng Listatic void disconnectWindow(const sp<ANativeWindow>& window) {
4607574da5a501fc9289fee49fdaf1fdb9d47dae2b6Wu-cheng Li    if (window != 0) {
461c3da3434cb57f47284ea06bb9065eaa2fe033efbMathias Agopian        status_t result = native_window_api_disconnect(window.get(),
4627574da5a501fc9289fee49fdaf1fdb9d47dae2b6Wu-cheng Li                NATIVE_WINDOW_API_CAMERA);
4637574da5a501fc9289fee49fdaf1fdb9d47dae2b6Wu-cheng Li        if (result != NO_ERROR) {
4645ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block            ALOGW("native_window_api_disconnect failed: %s (%d)", strerror(-result),
4657574da5a501fc9289fee49fdaf1fdb9d47dae2b6Wu-cheng Li                    result);
4667574da5a501fc9289fee49fdaf1fdb9d47dae2b6Wu-cheng Li        }
4677574da5a501fc9289fee49fdaf1fdb9d47dae2b6Wu-cheng Li    }
4687574da5a501fc9289fee49fdaf1fdb9d47dae2b6Wu-cheng Li}
4697574da5a501fc9289fee49fdaf1fdb9d47dae2b6Wu-cheng Li
47065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::disconnect() {
47165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int callingPid = getCallingPid();
47265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("disconnect E (pid %d)", callingPid);
47365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mLock);
47465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
47565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (checkPid() != NO_ERROR) {
4765ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block        ALOGW("different client - don't disconnect");
47765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
47865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
47965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
48065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mClientPid <= 0) {
48165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        LOG1("camera is unlocked (mClientPid = %d), don't tear down hardware", mClientPid);
48265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
48365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
48465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
48565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Make sure disconnect() is done once and once only, whether it is called
48665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // from the user directly, or called by the destructor.
48765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mHardware == 0) return;
48865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
48965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("hardware teardown");
49065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Before destroying mHardware, we must make sure it's in the
49165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // idle state.
49265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Turn off all messages.
49365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    disableMsgType(CAMERA_MSG_ALL_MSGS);
49465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardware->stopPreview();
49565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardware->cancelPicture();
49665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // Release the hardware resources.
49765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardware->release();
49803dfce9672b36c1a334959a602f909b8410bec50Mathias Agopian
4994b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis    // Release the held ANativeWindow resources.
5004b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis    if (mPreviewWindow != 0) {
5017574da5a501fc9289fee49fdaf1fdb9d47dae2b6Wu-cheng Li        disconnectWindow(mPreviewWindow);
5024b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis        mPreviewWindow = 0;
5034b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis        mHardware->setPreviewWindow(mPreviewWindow);
5044b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis    }
50565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardware.clear();
50665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
50765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraService->removeClient(mCameraClient);
50865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraService->setCameraFree(mCameraId);
50965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
51065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("disconnect X (pid %d)", callingPid);
51165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
51265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
51365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
51465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5150ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennisstatus_t CameraService::Client::setPreviewWindow(const sp<IBinder>& binder,
5160ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis        const sp<ANativeWindow>& window) {
51765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mLock);
51865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t result = checkPidAndHardware();
51965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (result != NO_ERROR) return result;
52065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
52165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // return if no change in surface.
5228b1027d3f873fc15c70f8645f1856936b69241a4Mathias Agopian    if (binder == mSurface) {
5230ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis        return NO_ERROR;
52465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
52565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5260ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis    if (window != 0) {
527c3da3434cb57f47284ea06bb9065eaa2fe033efbMathias Agopian        result = native_window_api_connect(window.get(), NATIVE_WINDOW_API_CAMERA);
5280ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis        if (result != NO_ERROR) {
52929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("native_window_api_connect failed: %s (%d)", strerror(-result),
5300ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis                    result);
5310ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis            return result;
5320ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis        }
53365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
534bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis
5350ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis    // If preview has been already started, register preview buffers now.
53665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mHardware->previewEnabled()) {
5370ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis        if (window != 0) {
5389bc7af17974f448291a44912566ec7472a0d798bMathias Agopian            native_window_set_scaling_mode(window.get(),
5399bc7af17974f448291a44912566ec7472a0d798bMathias Agopian                    NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
5400ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis            native_window_set_buffers_transform(window.get(), mOrientation);
5410ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis            result = mHardware->setPreviewWindow(window);
54265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
54365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
54465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5450ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis    if (result == NO_ERROR) {
5460ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis        // Everything has succeeded.  Disconnect the old window and remember the
5470ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis        // new window.
5480ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis        disconnectWindow(mPreviewWindow);
5490ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis        mSurface = binder;
5500ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis        mPreviewWindow = window;
5510ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis    } else {
5520ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis        // Something went wrong after we connected to the new window, so
5530ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis        // disconnect here.
5540ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis        disconnectWindow(window);
5550ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis    }
5560ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis
55765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return result;
55865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
55965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
5600ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis// set the Surface that the preview will use
5610ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennisstatus_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) {
5620ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis    LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid());
5630ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis
5640ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis    sp<IBinder> binder(surface != 0 ? surface->asBinder() : 0);
5650ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis    sp<ANativeWindow> window(surface);
5660ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis    return setPreviewWindow(binder, window);
5670ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis}
5680ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis
569bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis// set the SurfaceTexture that the preview will use
570bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennisstatus_t CameraService::Client::setPreviewTexture(
571bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis        const sp<ISurfaceTexture>& surfaceTexture) {
572bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis    LOG1("setPreviewTexture(%p) (pid %d)", surfaceTexture.get(),
573bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis            getCallingPid());
574bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis
5750ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis    sp<IBinder> binder;
5760ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis    sp<ANativeWindow> window;
577bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis    if (surfaceTexture != 0) {
5780ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis        binder = surfaceTexture->asBinder();
5790ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis        window = new SurfaceTextureClient(surfaceTexture);
580bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis    }
5810ed3ec00d0242c9dc77532fe0cf0082645b6662cJamie Gennis    return setPreviewWindow(binder, window);
582bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis}
583bfa33aae4f54c0020a0568b16a3acb7b30b6ca3dJamie Gennis
58465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// set the preview callback flag to affect how the received frames from
58565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// preview are handled.
58665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::setPreviewCallbackFlag(int callback_flag) {
58765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("setPreviewCallbackFlag(%d) (pid %d)", callback_flag, getCallingPid());
58865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mLock);
58965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (checkPidAndHardware() != NO_ERROR) return;
59065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
59165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mPreviewCallbackFlag = callback_flag;
5929e626526453f91999bdf3de4c2ec8e55c5d90511Iliyan Malchev    if (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) {
5930667de7038238c31af77865eb6d83c5ae9ca1b1eWu-cheng Li        enableMsgType(CAMERA_MSG_PREVIEW_FRAME);
5940667de7038238c31af77865eb6d83c5ae9ca1b1eWu-cheng Li    } else {
5950667de7038238c31af77865eb6d83c5ae9ca1b1eWu-cheng Li        disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
59665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
59765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
59865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
59965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// start preview mode
60065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::startPreview() {
60165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("startPreview (pid %d)", getCallingPid());
60265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return startCameraMode(CAMERA_PREVIEW_MODE);
60365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
60465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
60565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// start recording mode
60665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::startRecording() {
60765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("startRecording (pid %d)", getCallingPid());
60865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return startCameraMode(CAMERA_RECORDING_MODE);
60965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
61065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
61165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// start preview or recording
61265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::startCameraMode(camera_mode mode) {
61365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("startCameraMode(%d)", mode);
61465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mLock);
61565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t result = checkPidAndHardware();
61665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (result != NO_ERROR) return result;
61765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
61865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch(mode) {
61965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case CAMERA_PREVIEW_MODE:
6204b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis            if (mSurface == 0 && mPreviewWindow == 0) {
62165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                LOG1("mSurface is not set yet.");
62265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                // still able to start preview in this case.
62365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
62465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return startPreviewMode();
62565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case CAMERA_RECORDING_MODE:
6264b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis            if (mSurface == 0 && mPreviewWindow == 0) {
62729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block                ALOGE("mSurface or mPreviewWindow must be set before startRecordingMode.");
62865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                return INVALID_OPERATION;
62965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
63065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return startRecordingMode();
63165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        default:
63265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return UNKNOWN_ERROR;
63365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
63465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
63565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
63665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::startPreviewMode() {
63765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("startPreviewMode");
63865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t result = NO_ERROR;
63965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
64065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // if preview has been enabled, nothing needs to be done
64165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mHardware->previewEnabled()) {
64265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_ERROR;
64365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
64465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
64503dfce9672b36c1a334959a602f909b8410bec50Mathias Agopian    if (mPreviewWindow != 0) {
6469bc7af17974f448291a44912566ec7472a0d798bMathias Agopian        native_window_set_scaling_mode(mPreviewWindow.get(),
6479bc7af17974f448291a44912566ec7472a0d798bMathias Agopian                NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
64803dfce9672b36c1a334959a602f909b8410bec50Mathias Agopian        native_window_set_buffers_transform(mPreviewWindow.get(),
64903dfce9672b36c1a334959a602f909b8410bec50Mathias Agopian                mOrientation);
65065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
65103dfce9672b36c1a334959a602f909b8410bec50Mathias Agopian    mHardware->setPreviewWindow(mPreviewWindow);
65203dfce9672b36c1a334959a602f909b8410bec50Mathias Agopian    result = mHardware->startPreview();
65303dfce9672b36c1a334959a602f909b8410bec50Mathias Agopian
65465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return result;
65565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
65665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
65765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::startRecordingMode() {
65865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("startRecordingMode");
65965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t result = NO_ERROR;
66065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
66165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // if recording has been enabled, nothing needs to be done
66265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mHardware->recordingEnabled()) {
66365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NO_ERROR;
66465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
66565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
66665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // if preview has not been started, start preview first
66765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!mHardware->previewEnabled()) {
66865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        result = startPreviewMode();
66965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (result != NO_ERROR) {
67065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return result;
67165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
67265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
67365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
67465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // start recording mode
67565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    enableMsgType(CAMERA_MSG_VIDEO_FRAME);
67665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraService->playSound(SOUND_RECORDING);
67765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    result = mHardware->startRecording();
67865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (result != NO_ERROR) {
67929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("mHardware->startRecording() failed with status %d", result);
68065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
68165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return result;
68265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
68365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
68465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// stop preview mode
68565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::stopPreview() {
68665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("stopPreview (pid %d)", getCallingPid());
68765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mLock);
68865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (checkPidAndHardware() != NO_ERROR) return;
68965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
6904b79168835965cf0fc41ebe2a367e22b4cb20d08Jamie Gennis
69165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
69265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardware->stopPreview();
69365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
69465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mPreviewBuffer.clear();
69565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
69665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
69765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// stop recording mode
69865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::stopRecording() {
69965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("stopRecording (pid %d)", getCallingPid());
70065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mLock);
70165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (checkPidAndHardware() != NO_ERROR) return;
70265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
70365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mCameraService->playSound(SOUND_RECORDING);
70465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    disableMsgType(CAMERA_MSG_VIDEO_FRAME);
70565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardware->stopRecording();
70665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
70765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mPreviewBuffer.clear();
70865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
70965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
71065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// release a recording frame
71165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::releaseRecordingFrame(const sp<IMemory>& mem) {
71265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mLock);
71365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (checkPidAndHardware() != NO_ERROR) return;
71465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardware->releaseRecordingFrame(mem);
71565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
71665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
717e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dongstatus_t CameraService::Client::storeMetaDataInBuffers(bool enabled)
718e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dong{
719e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dong    LOG1("storeMetaDataInBuffers: %s", enabled? "true": "false");
720e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dong    Mutex::Autolock lock(mLock);
721e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dong    if (checkPidAndHardware() != NO_ERROR) {
722e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dong        return UNKNOWN_ERROR;
723e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dong    }
724e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dong    return mHardware->storeMetaDataInBuffers(enabled);
725e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dong}
726e2ad6734eccc4b9ea7857c747ff9469a9c11ba09James Dong
72765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool CameraService::Client::previewEnabled() {
72865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("previewEnabled (pid %d)", getCallingPid());
72965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
73065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mLock);
73165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (checkPidAndHardware() != NO_ERROR) return false;
73265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mHardware->previewEnabled();
73365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
73465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
73565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool CameraService::Client::recordingEnabled() {
73665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("recordingEnabled (pid %d)", getCallingPid());
73765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
73865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mLock);
73965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (checkPidAndHardware() != NO_ERROR) return false;
74065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mHardware->recordingEnabled();
74165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
74265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
74365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::autoFocus() {
74465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("autoFocus (pid %d)", getCallingPid());
74565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
74665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mLock);
74765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t result = checkPidAndHardware();
74865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (result != NO_ERROR) return result;
74965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
75065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mHardware->autoFocus();
75165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
75265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
75365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::cancelAutoFocus() {
75465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("cancelAutoFocus (pid %d)", getCallingPid());
75565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
75665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mLock);
75765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t result = checkPidAndHardware();
75865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (result != NO_ERROR) return result;
75965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
76065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mHardware->cancelAutoFocus();
76165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
76265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
76365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// take a picture - image is returned in callback
764e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dongstatus_t CameraService::Client::takePicture(int msgType) {
765e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong    LOG1("takePicture (pid %d): 0x%x", getCallingPid(), msgType);
76665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
76765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mLock);
76865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t result = checkPidAndHardware();
76965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (result != NO_ERROR) return result;
77065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
771e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong    if ((msgType & CAMERA_MSG_RAW_IMAGE) &&
772e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong        (msgType & CAMERA_MSG_RAW_IMAGE_NOTIFY)) {
77329357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("CAMERA_MSG_RAW_IMAGE and CAMERA_MSG_RAW_IMAGE_NOTIFY"
774e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong                " cannot be both enabled");
775e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong        return BAD_VALUE;
776e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong    }
777e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong
778e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong    // We only accept picture related message types
779e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong    // and ignore other types of messages for takePicture().
780e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong    int picMsgType = msgType
781e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong                        & (CAMERA_MSG_SHUTTER |
782e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong                           CAMERA_MSG_POSTVIEW_FRAME |
783e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong                           CAMERA_MSG_RAW_IMAGE |
784e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong                           CAMERA_MSG_RAW_IMAGE_NOTIFY |
785e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong                           CAMERA_MSG_COMPRESSED_IMAGE);
786e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong
787e468ac57f6e8afc6078c76d4eb1ac327112a3de0James Dong    enableMsgType(picMsgType);
78865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
78965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mHardware->takePicture();
79065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
79165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
79265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// set preview/capture parameters - key/value pairs
79365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::setParameters(const String8& params) {
79465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("setParameters (pid %d) (%s)", getCallingPid(), params.string());
79565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
79665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mLock);
79765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t result = checkPidAndHardware();
79865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (result != NO_ERROR) return result;
79965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
80065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    CameraParameters p(params);
80165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mHardware->setParameters(p);
80265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
80365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
80465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// get preview/capture parameters - key/value pairs
80565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias AgopianString8 CameraService::Client::getParameters() const {
80665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mLock);
80765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (checkPidAndHardware() != NO_ERROR) return String8();
80865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
80965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 params(mHardware->getParameters().flatten());
81065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("getParameters (pid %d) (%s)", getCallingPid(), params.string());
81165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return params;
81265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
81365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
814b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra// enable shutter sound
815b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatrastatus_t CameraService::Client::enableShutterSound(bool enable) {
816b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra    LOG1("enableShutterSound (pid %d)", getCallingPid());
817b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra
818b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra    status_t result = checkPidAndHardware();
819b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra    if (result != NO_ERROR) return result;
820b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra
821b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra    if (enable) {
822b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra        mPlayShutterSound = true;
823b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra        return OK;
824b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra    }
825b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra
826b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra    // Disabling shutter sound may not be allowed. In that case only
827b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra    // allow the mediaserver process to disable the sound.
828b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra    char value[PROPERTY_VALUE_MAX];
829b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra    property_get("ro.camera.sound.forced", value, "0");
830b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra    if (strcmp(value, "0") != 0) {
831b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra        // Disabling shutter sound is not allowed. Deny if the current
832b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra        // process is not mediaserver.
833b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra        if (getCallingPid() != getpid()) {
83429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block            ALOGE("Failed to disable shutter sound. Permission denied (pid %d)", getCallingPid());
835b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra            return PERMISSION_DENIED;
836b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra        }
837b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra    }
838b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra
839b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra    mPlayShutterSound = false;
840b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra    return OK;
841b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra}
842b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra
84365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
84465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG1("sendCommand (pid %d)", getCallingPid());
8454a73f3da3501db6e95473a4a653d6319c6d618e2Wu-cheng Li    int orientation;
84665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    Mutex::Autolock lock(mLock);
84765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    status_t result = checkPidAndHardware();
84865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (result != NO_ERROR) return result;
84965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
85065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (cmd == CAMERA_CMD_SET_DISPLAY_ORIENTATION) {
851e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li        // Mirror the preview if the camera is front-facing.
852e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li        orientation = getOrientation(arg1, mCameraFacing == CAMERA_FACING_FRONT);
853e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li        if (orientation == -1) return BAD_VALUE;
854e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li
8554a73f3da3501db6e95473a4a653d6319c6d618e2Wu-cheng Li        if (mOrientation != orientation) {
8564a73f3da3501db6e95473a4a653d6319c6d618e2Wu-cheng Li            mOrientation = orientation;
857b9f588677910cac6ffc0346092bfcfe1c6620b90Wu-cheng Li            if (mPreviewWindow != 0) {
858b9f588677910cac6ffc0346092bfcfe1c6620b90Wu-cheng Li                native_window_set_buffers_transform(mPreviewWindow.get(),
859b9f588677910cac6ffc0346092bfcfe1c6620b90Wu-cheng Li                        mOrientation);
860b9f588677910cac6ffc0346092bfcfe1c6620b90Wu-cheng Li            }
8614a73f3da3501db6e95473a4a653d6319c6d618e2Wu-cheng Li        }
86265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return OK;
863b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra    } else if (cmd == CAMERA_CMD_ENABLE_SHUTTER_SOUND) {
864b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra        switch (arg1) {
865b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra            case 0:
866b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra                enableShutterSound(false);
867b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra                break;
868b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra            case 1:
869b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra                enableShutterSound(true);
870b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra                break;
871b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra            default:
872b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra                return BAD_VALUE;
873b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra        }
874b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra        return OK;
8753b7b358d1a45844ca427626554ff81f472fd1583Nipun Kwatra    } else if (cmd == CAMERA_CMD_PLAY_RECORDING_SOUND) {
8763b7b358d1a45844ca427626554ff81f472fd1583Nipun Kwatra        mCameraService->playSound(SOUND_RECORDING);
87765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
87865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
87965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return mHardware->sendCommand(cmd, arg1, arg2);
88065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
88165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
88265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
88365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
88465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::enableMsgType(int32_t msgType) {
88565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_or(msgType, &mMsgEnabled);
88665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardware->enableMsgType(msgType);
88765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
88865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
88965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::disableMsgType(int32_t msgType) {
89065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    android_atomic_and(~msgType, &mMsgEnabled);
89165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mHardware->disableMsgType(msgType);
89265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
89365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
89465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian#define CHECK_MESSAGE_INTERVAL 10 // 10ms
89565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianbool CameraService::Client::lockIfMessageWanted(int32_t msgType) {
89665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int sleepCount = 0;
89765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    while (mMsgEnabled & msgType) {
89865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mLock.tryLock() == NO_ERROR) {
89965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (sleepCount > 0) {
90065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                LOG1("lockIfMessageWanted(%d): waited for %d ms",
90165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    msgType, sleepCount * CHECK_MESSAGE_INTERVAL);
90265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
90365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            return true;
90465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
90565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (sleepCount++ == 0) {
90665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            LOG1("lockIfMessageWanted(%d): enter sleep", msgType);
90765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
90865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        usleep(CHECK_MESSAGE_INTERVAL * 1000);
90965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
9105ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block    ALOGW("lockIfMessageWanted(%d): dropped unwanted message", msgType);
91165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return false;
91265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
91365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
91465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
91565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
91665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Converts from a raw pointer to the client to a strong pointer during a
91765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// hardware callback. This requires the callbacks only happen when the client
91865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// is still alive.
91965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopiansp<CameraService::Client> CameraService::Client::getClientFromCookie(void* user) {
92065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<Client> client = gCameraService->getClientById((int) user);
92165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
92265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // This could happen if the Client is in the process of shutting down (the
92365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // last strong reference is gone, but the destructor hasn't finished
92465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // stopping the hardware).
92565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (client == 0) return NULL;
92665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
92765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // The checks below are not necessary and are for debugging only.
92865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (client->mCameraService.get() != gCameraService) {
92929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("mismatch service!");
93065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NULL;
93165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
93265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
93365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (client->mHardware == 0) {
93429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("mHardware == 0: callback after disconnect()?");
93565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return NULL;
93665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
93765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
93865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return client;
93965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
94065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
94165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// Callback messages can be dispatched to internal handlers or pass to our
94265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// client's callback functions, depending on the message type.
94365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//
94465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// notifyCallback:
94565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//      CAMERA_MSG_SHUTTER              handleShutter
94665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//      (others)                        c->notifyCallback
94765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// dataCallback:
94865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//      CAMERA_MSG_PREVIEW_FRAME        handlePreviewData
94965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//      CAMERA_MSG_POSTVIEW_FRAME       handlePostview
95065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//      CAMERA_MSG_RAW_IMAGE            handleRawPicture
95165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//      CAMERA_MSG_COMPRESSED_IMAGE     handleCompressedPicture
95265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//      (others)                        c->dataCallback
95365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// dataCallbackTimestamp
95465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//      (others)                        c->dataCallbackTimestamp
95565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian//
95665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// NOTE: the *Callback functions grab mLock of the client before passing
95765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// control to handle* functions. So the handle* functions must release the
95865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// lock before calling the ICameraClient's callbacks, so those callbacks can
95965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// invoke methods in the Client class again (For example, the preview frame
96065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// callback may want to releaseRecordingFrame). The handle* functions must
96165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// release the lock after all accesses to member variables, so it must be
96265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// handled very carefully.
96365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
96465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::notifyCallback(int32_t msgType, int32_t ext1,
96565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int32_t ext2, void* user) {
96665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG2("notifyCallback(%d)", msgType);
96765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
96865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<Client> client = getClientFromCookie(user);
96965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (client == 0) return;
97065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!client->lockIfMessageWanted(msgType)) return;
97165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
97265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    switch (msgType) {
97365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case CAMERA_MSG_SHUTTER:
97465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            // ext1 is the dimension of the yuv picture.
975108dddf924d714c811dd565b8f4c7a0178cca2f2Iliyan Malchev            client->handleShutter();
97665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
97765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        default:
97865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            client->handleGenericNotify(msgType, ext1, ext2);
97965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
98065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
98165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
98265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
98365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::dataCallback(int32_t msgType,
984ff09ef8f18eed29bce50c7817df2fd52d2b50cf6Wu-cheng Li        const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata, void* user) {
98565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG2("dataCallback(%d)", msgType);
98665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
98765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<Client> client = getClientFromCookie(user);
98865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (client == 0) return;
98965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (!client->lockIfMessageWanted(msgType)) return;
99065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
99157c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li    if (dataPtr == 0 && metadata == NULL) {
99229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Null data returned in data callback");
99365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
99465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
99565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
99665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
99757c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li    switch (msgType & ~CAMERA_MSG_PREVIEW_METADATA) {
99865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case CAMERA_MSG_PREVIEW_FRAME:
99957c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li            client->handlePreviewData(msgType, dataPtr, metadata);
100065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
100165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case CAMERA_MSG_POSTVIEW_FRAME:
100265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            client->handlePostview(dataPtr);
100365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
100465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case CAMERA_MSG_RAW_IMAGE:
100565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            client->handleRawPicture(dataPtr);
100665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
100765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        case CAMERA_MSG_COMPRESSED_IMAGE:
100865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            client->handleCompressedPicture(dataPtr);
100965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
101065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        default:
101157c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li            client->handleGenericData(msgType, dataPtr, metadata);
101265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
101365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
101465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
101565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
101665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::dataCallbackTimestamp(nsecs_t timestamp,
101765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int32_t msgType, const sp<IMemory>& dataPtr, void* user) {
101865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG2("dataCallbackTimestamp(%d)", msgType);
101965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
102065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<Client> client = getClientFromCookie(user);
102165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (client == 0) return;
1022986ef2ad4c96952711d87af481f3afb40aa10775James Dong    if (!client->lockIfMessageWanted(msgType)) return;
102365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
102465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (dataPtr == 0) {
102529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("Null data returned in data with timestamp callback");
102665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        client->handleGenericNotify(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0);
102765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
102865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
102965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
103065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    client->handleGenericDataTimestamp(timestamp, msgType, dataPtr);
103165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
103265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
103365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// snapshot taken callback
1034108dddf924d714c811dd565b8f4c7a0178cca2f2Iliyan Malchevvoid CameraService::Client::handleShutter(void) {
1035b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra    if (mPlayShutterSound) {
1036b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra        mCameraService->playSound(SOUND_SHUTTER);
1037b5ca4618a722a21f084fe8bfc1c2992749ccd3f0Nipun Kwatra    }
103865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
103965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ICameraClient> c = mCameraClient;
104065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (c != 0) {
104165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mLock.unlock();
104265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        c->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0);
104365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!lockIfMessageWanted(CAMERA_MSG_SHUTTER)) return;
104465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
104565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    disableMsgType(CAMERA_MSG_SHUTTER);
104665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
104765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLock.unlock();
104865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
104965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
105065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// preview callback - frame buffer update
105157c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Livoid CameraService::Client::handlePreviewData(int32_t msgType,
105257c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li                                              const sp<IMemory>& mem,
105357c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li                                              camera_frame_metadata_t *metadata) {
105465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ssize_t offset;
105565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t size;
105665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
105765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
105865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // local copy of the callback flags
105965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int flags = mPreviewCallbackFlag;
106065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
106165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // is callback enabled?
10629e626526453f91999bdf3de4c2ec8e55c5d90511Iliyan Malchev    if (!(flags & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK)) {
106365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // If the enable bit is off, the copy-out and one-shot bits are ignored
106465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        LOG2("frame callback is disabled");
106565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mLock.unlock();
106665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
106765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
106865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
106965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // hold a strong pointer to the client
107065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ICameraClient> c = mCameraClient;
107165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
107265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // clear callback flags if no client or one-shot mode
10739e626526453f91999bdf3de4c2ec8e55c5d90511Iliyan Malchev    if (c == 0 || (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) {
107465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        LOG2("Disable preview callback");
10759e626526453f91999bdf3de4c2ec8e55c5d90511Iliyan Malchev        mPreviewCallbackFlag &= ~(CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK |
10769e626526453f91999bdf3de4c2ec8e55c5d90511Iliyan Malchev                                  CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK |
10779e626526453f91999bdf3de4c2ec8e55c5d90511Iliyan Malchev                                  CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK);
10780667de7038238c31af77865eb6d83c5ae9ca1b1eWu-cheng Li        disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
107965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
108065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
108165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (c != 0) {
108265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // Is the received frame copied out or not?
10839e626526453f91999bdf3de4c2ec8e55c5d90511Iliyan Malchev        if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) {
108465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            LOG2("frame is copied");
108557c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li            copyFrameAndPostCopiedFrame(msgType, c, heap, offset, size, metadata);
108665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        } else {
108765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            LOG2("frame is forwarded");
108865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            mLock.unlock();
108957c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li            c->dataCallback(msgType, mem, metadata);
109065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
109165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
109265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mLock.unlock();
109365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
109465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
109565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
109665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// picture callback - postview image ready
109765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handlePostview(const sp<IMemory>& mem) {
109865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    disableMsgType(CAMERA_MSG_POSTVIEW_FRAME);
109965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
110065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ICameraClient> c = mCameraClient;
110165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLock.unlock();
110265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (c != 0) {
110357c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li        c->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem, NULL);
110465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
110565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
110665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
110765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// picture callback - raw image ready
110865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handleRawPicture(const sp<IMemory>& mem) {
110965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    disableMsgType(CAMERA_MSG_RAW_IMAGE);
111065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
111165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    ssize_t offset;
111265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    size_t size;
111365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
111465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
111565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ICameraClient> c = mCameraClient;
111665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLock.unlock();
111765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (c != 0) {
111857c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li        c->dataCallback(CAMERA_MSG_RAW_IMAGE, mem, NULL);
111965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
112065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
112165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
112265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// picture callback - compressed picture ready
112365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handleCompressedPicture(const sp<IMemory>& mem) {
112465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE);
112565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
112665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ICameraClient> c = mCameraClient;
112765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLock.unlock();
112865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (c != 0) {
112957c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li        c->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL);
113065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
113165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
113265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
113365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
113465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handleGenericNotify(int32_t msgType,
113565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int32_t ext1, int32_t ext2) {
113665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ICameraClient> c = mCameraClient;
113765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLock.unlock();
113865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (c != 0) {
113965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        c->notifyCallback(msgType, ext1, ext2);
114065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
114165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
114265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
114365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handleGenericData(int32_t msgType,
114457c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li    const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) {
114565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ICameraClient> c = mCameraClient;
114665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLock.unlock();
114765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (c != 0) {
114857c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li        c->dataCallback(msgType, dataPtr, metadata);
114965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
115065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
115165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
115265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::handleGenericDataTimestamp(nsecs_t timestamp,
115365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    int32_t msgType, const sp<IMemory>& dataPtr) {
115465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<ICameraClient> c = mCameraClient;
115565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLock.unlock();
115665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (c != 0) {
115765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
115865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
115965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
116065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
116165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianvoid CameraService::Client::copyFrameAndPostCopiedFrame(
116257c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li        int32_t msgType, const sp<ICameraClient>& client,
116357c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li        const sp<IMemoryHeap>& heap, size_t offset, size_t size,
116457c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li        camera_frame_metadata_t *metadata) {
116565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    LOG2("copyFrameAndPostCopiedFrame");
116665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // It is necessary to copy out of pmem before sending this to
116765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // the callback. For efficiency, reuse the same MemoryHeapBase
116865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // provided it's big enough. Don't allocate the memory or
116965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // perform the copy if there's no callback.
117065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    // hold the preview lock while we grab a reference to the preview buffer
117165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<MemoryHeapBase> previewBuffer;
117265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
117365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mPreviewBuffer == 0) {
117465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
117565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else if (size > mPreviewBuffer->virtualSize()) {
117665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mPreviewBuffer.clear();
117765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mPreviewBuffer = new MemoryHeapBase(size, 0, NULL);
117865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
117965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (mPreviewBuffer == 0) {
118029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("failed to allocate space for preview buffer");
118165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mLock.unlock();
118265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
118365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
118465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    previewBuffer = mPreviewBuffer;
118565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
118665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    memcpy(previewBuffer->base(), (uint8_t *)heap->base() + offset, size);
118765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
118865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    sp<MemoryBase> frame = new MemoryBase(previewBuffer, 0, size);
118965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (frame == 0) {
119029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block        ALOGE("failed to allocate space for frame callback");
119165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        mLock.unlock();
119265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        return;
119365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
119465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
119565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    mLock.unlock();
119657c86189bc07d9ccb0fd044e66df736d0bf19639Wu-cheng Li    client->dataCallback(msgType, frame, metadata);
119765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
119865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
1199e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Liint CameraService::Client::getOrientation(int degrees, bool mirror) {
1200e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li    if (!mirror) {
1201e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li        if (degrees == 0) return 0;
1202e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li        else if (degrees == 90) return HAL_TRANSFORM_ROT_90;
1203e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li        else if (degrees == 180) return HAL_TRANSFORM_ROT_180;
1204e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li        else if (degrees == 270) return HAL_TRANSFORM_ROT_270;
1205e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li    } else {  // Do mirror (horizontal flip)
1206e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li        if (degrees == 0) {           // FLIP_H and ROT_0
1207e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li            return HAL_TRANSFORM_FLIP_H;
1208e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li        } else if (degrees == 90) {   // FLIP_H and ROT_90
1209e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li            return HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
1210e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li        } else if (degrees == 180) {  // FLIP_H and ROT_180
1211e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li            return HAL_TRANSFORM_FLIP_V;
1212e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li        } else if (degrees == 270) {  // FLIP_H and ROT_270
1213e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li            return HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
1214e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li        }
1215e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li    }
121629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block    ALOGE("Invalid setDisplayOrientation degrees=%d", degrees);
1217e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li    return -1;
1218e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li}
1219e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li
1220e09591eff55fdff1868b32c3e046c62f800330fcWu-cheng Li
122165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian// ----------------------------------------------------------------------------
122265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
122365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockRetries = 50;
122465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic const int kDumpLockSleep = 60000;
122565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
122665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatic bool tryLock(Mutex& mutex)
122765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian{
122865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    bool locked = false;
122965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    for (int i = 0; i < kDumpLockRetries; ++i) {
123065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (mutex.tryLock() == NO_ERROR) {
123165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            locked = true;
123265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            break;
123365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
123465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        usleep(kDumpLockSleep);
123565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
123665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return locked;
123765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
123865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
123965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopianstatus_t CameraService::dump(int fd, const Vector<String16>& args) {
124065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    static const char* kDeadlockedString = "CameraService may be deadlocked\n";
124165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
124265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    const size_t SIZE = 256;
124365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    char buffer[SIZE];
124465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    String8 result;
124565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
124665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        snprintf(buffer, SIZE, "Permission Denial: "
124765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                "can't dump CameraService from pid=%d, uid=%d\n",
124865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                getCallingPid(),
124965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                getCallingUid());
125065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        result.append(buffer);
125165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        write(fd, result.string(), result.size());
125265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    } else {
125365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool locked = tryLock(mServiceLock);
125465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // failed to lock - CameraService is probably deadlocked
125565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!locked) {
125665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            String8 result(kDeadlockedString);
125765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
125865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
125965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
126065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        bool hasClient = false;
126165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (int i = 0; i < mNumberOfCameras; i++) {
126265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            sp<Client> client = mClient[i].promote();
126365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (client == 0) continue;
126465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            hasClient = true;
126565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            sprintf(buffer, "Client[%d] (%p) PID: %d\n",
126665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    i,
126765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    client->getCameraClient()->asBinder().get(),
126865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                    client->mClientPid);
126965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            result.append(buffer);
127065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
127165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            client->mHardware->dump(fd, args);
127265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
127365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (!hasClient) {
127465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            result.append("No camera client yet.\n");
127565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            write(fd, result.string(), result.size());
127665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
127765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
127865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        if (locked) mServiceLock.unlock();
127965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
128065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        // change logging level
128165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        int n = args.size();
128265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        for (int i = 0; i + 1 < n; i++) {
128365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            if (args[i] == String16("-v")) {
128465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                String8 levelStr(args[i+1]);
128565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                int level = atoi(levelStr.string());
128665ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                sprintf(buffer, "Set Log Level to %d", level);
128765ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                result.append(buffer);
128865ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian                setLogLevel(level);
128965ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian            }
129065ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian        }
129165ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    }
129265ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian    return NO_ERROR;
129365ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}
129465ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian
129565ab47156e1c7dfcd8cc4266253a5ff30219e7f0Mathias Agopian}; // namespace android
1296