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