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