/*
**
** Copyright (C) 2008, The Android Open Source Project
** Copyright (C) 2008 HTC Inc.
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/

//#define LOG_NDEBUG 0
#define LOG_TAG "Camera"
#include <utils/Log.h>
#include <binder/IServiceManager.h>
#include <utils/threads.h>
#include <binder/IMemory.h>
#include <ui/Surface.h>
#include <ui/Camera.h>
#include <ui/ICameraService.h>

namespace android {

// client singleton for camera service binder interface
Mutex Camera::mLock;
sp<ICameraService> Camera::mCameraService;
sp<Camera::DeathNotifier> Camera::mDeathNotifier;

// establish binder interface to camera service
const sp<ICameraService>& Camera::getCameraService()
{
    Mutex::Autolock _l(mLock);
    if (mCameraService.get() == 0) {
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder;
        do {
            binder = sm->getService(String16("media.camera"));
            if (binder != 0)
                break;
            LOGW("CameraService not published, waiting...");
            usleep(500000); // 0.5 s
        } while(true);
        if (mDeathNotifier == NULL) {
            mDeathNotifier = new DeathNotifier();
        }
        binder->linkToDeath(mDeathNotifier);
        mCameraService = interface_cast<ICameraService>(binder);
    }
    LOGE_IF(mCameraService==0, "no CameraService!?");
    return mCameraService;
}

// ---------------------------------------------------------------------------

Camera::Camera()
{
    init();
}

// construct a camera client from an existing camera remote
sp<Camera> Camera::create(const sp<ICamera>& camera)
{
     LOGV("create");
     if (camera == 0) {
         LOGE("camera remote is a NULL pointer");
         return 0;
     }

    sp<Camera> c = new Camera();
    if (camera->connect(c) == NO_ERROR) {
        c->mStatus = NO_ERROR;
        c->mCamera = camera;
        camera->asBinder()->linkToDeath(c);
    }
    return c;
}

void Camera::init()
{
    mStatus = UNKNOWN_ERROR;
    mShutterCallback = 0;
    mShutterCallbackCookie = 0;
    mRawCallback = 0;
    mRawCallbackCookie = 0;
    mJpegCallback = 0;
    mJpegCallbackCookie = 0;
    mPreviewCallback = 0;
    mPreviewCallbackCookie = 0;
    mRecordingCallback = 0;
    mRecordingCallbackCookie = 0;
    mErrorCallback = 0;
    mErrorCallbackCookie = 0;
    mAutoFocusCallback = 0;
    mAutoFocusCallbackCookie = 0;
}

Camera::~Camera()
{
    disconnect();
}

sp<Camera> Camera::connect()
{
    LOGV("connect");
    sp<Camera> c = new Camera();
    const sp<ICameraService>& cs = getCameraService();
    if (cs != 0) {
        c->mCamera = cs->connect(c);
    }
    if (c->mCamera != 0) {
        c->mCamera->asBinder()->linkToDeath(c);
        c->mStatus = NO_ERROR;
    } else {
        c.clear();
    }
    return c;
}

void Camera::disconnect()
{
    LOGV("disconnect");
    if (mCamera != 0) {
        mErrorCallback = 0;
        mCamera->disconnect();
        mCamera = 0;
    }
}

status_t Camera::reconnect()
{
    LOGV("reconnect");
    sp <ICamera> c = mCamera;
    if (c == 0) return NO_INIT;
    return c->connect(this);
}

sp<ICamera> Camera::remote()
{
    return mCamera;
}

status_t Camera::lock()
{
    sp <ICamera> c = mCamera;
    if (c == 0) return NO_INIT;
    return c->lock();
}

status_t Camera::unlock()
{
    sp <ICamera> c = mCamera;
    if (c == 0) return NO_INIT;
    return c->unlock();
}

// pass the buffered ISurface to the camera service
status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
{
    LOGV("setPreviewDisplay");
    if (surface == 0) {
        LOGE("app passed NULL surface");
        return NO_INIT;
    }
    sp <ICamera> c = mCamera;
    if (c == 0) return NO_INIT;
    return c->setPreviewDisplay(surface->getISurface());
}

status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
{
    LOGV("setPreviewDisplay");
    if (surface == 0) {
        LOGE("app passed NULL surface");
        return NO_INIT;
    }
    sp <ICamera> c = mCamera;
    if (c == 0) return NO_INIT;
    return c->setPreviewDisplay(surface);
}


// start preview mode, must call setPreviewDisplay first
status_t Camera::startPreview()
{
    LOGV("startPreview");
    sp <ICamera> c = mCamera;
    if (c == 0) return NO_INIT;
    return c->startPreview();
}

// start recording mode, must call setPreviewDisplay first
status_t Camera::startRecording()
{
    LOGV("startRecording");
    sp <ICamera> c = mCamera;
    if (c == 0) return NO_INIT;
    return c->startRecording();
}

// stop preview mode
void Camera::stopPreview()
{
    LOGV("stopPreview");
    sp <ICamera> c = mCamera;
    if (c == 0) return;
    c->stopPreview();
}

// stop recording mode
void Camera::stopRecording()
{
    LOGV("stopRecording");
    sp <ICamera> c = mCamera;
    if (c == 0) return;
    c->stopRecording();
}

// release a recording frame
void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
{
    LOGV("releaseRecordingFrame");
    sp <ICamera> c = mCamera;
    if (c == 0) return;
    c->releaseRecordingFrame(mem);
}

// get preview state
bool Camera::previewEnabled()
{
    LOGV("previewEnabled");
    sp <ICamera> c = mCamera;
    if (c == 0) return false;
    return c->previewEnabled();
}

// get recording state
bool Camera::recordingEnabled()
{
    LOGV("recordingEnabled");
    sp <ICamera> c = mCamera;
    if (c == 0) return false;
    return c->recordingEnabled();
}

status_t Camera::autoFocus()
{
    LOGV("autoFocus");
    sp <ICamera> c = mCamera;
    if (c == 0) return NO_INIT;
    return c->autoFocus();
}

// take a picture
status_t Camera::takePicture()
{
    LOGV("takePicture");
    sp <ICamera> c = mCamera;
    if (c == 0) return NO_INIT;
    return c->takePicture();
}

// set preview/capture parameters - key/value pairs
status_t Camera::setParameters(const String8& params)
{
    LOGV("setParameters");
    sp <ICamera> c = mCamera;
    if (c == 0) return NO_INIT;
    return c->setParameters(params);
}

// get preview/capture parameters - key/value pairs
String8 Camera::getParameters() const
{
    LOGV("getParameters");
    String8 params;
    sp <ICamera> c = mCamera;
    if (c != 0) params = mCamera->getParameters();
    return params;
}

void Camera::setAutoFocusCallback(autofocus_callback cb, void *cookie)
{
    LOGV("setAutoFocusCallback");
    mAutoFocusCallback = cb;
    mAutoFocusCallbackCookie = cookie;
}

void Camera::setShutterCallback(shutter_callback cb, void *cookie)
{
    LOGV("setShutterCallback");
    mShutterCallback = cb;
    mShutterCallbackCookie = cookie;
}

void Camera::setRawCallback(frame_callback cb, void *cookie)
{
    LOGV("setRawCallback");
    mRawCallback = cb;
    mRawCallbackCookie = cookie;
}

void Camera::setJpegCallback(frame_callback cb, void *cookie)
{
    LOGV("setJpegCallback");
    mJpegCallback = cb;
    mJpegCallbackCookie = cookie;
}

void Camera::setPreviewCallback(frame_callback cb, void *cookie, int flag)
{
    LOGV("setPreviewCallback");
    mPreviewCallback = cb;
    mPreviewCallbackCookie = cookie;
    sp <ICamera> c = mCamera;
    if (c == 0) return;
    mCamera->setPreviewCallbackFlag(flag);
}

void Camera::setRecordingCallback(frame_callback cb, void *cookie)
{
    LOGV("setRecordingCallback");
    mRecordingCallback = cb;
    mRecordingCallbackCookie = cookie;
}

void Camera::setErrorCallback(error_callback cb, void *cookie)
{
    LOGV("setErrorCallback");
    mErrorCallback = cb;
    mErrorCallbackCookie = cookie;
}

// callback from camera service
void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
{
    switch(msgType) {
    case CAMERA_MSG_ERROR:
        LOGV("errorCallback");
        if (mErrorCallback) {
            mErrorCallback((status_t)ext1, mErrorCallbackCookie);
        }
        break;
    case CAMERA_MSG_FOCUS:
        LOGV("autoFocusCallback");
        if (mAutoFocusCallback) {
            mAutoFocusCallback((bool)ext1, mAutoFocusCallbackCookie);
        }
        break;
    case CAMERA_MSG_SHUTTER:
        LOGV("shutterCallback");
        if (mShutterCallback) {
            mShutterCallback(mShutterCallbackCookie);
        }
        break;
    default:
        LOGV("notifyCallback(%d, %d, %d)", msgType, ext1, ext2);
        break;
    }
}

// callback from camera service when frame or image is ready
void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
{
    switch(msgType) {
    case CAMERA_MSG_PREVIEW_FRAME:
        LOGV("previewCallback");
        if (mPreviewCallback) {
            mPreviewCallback(dataPtr, mPreviewCallbackCookie);
        }
        break;
    case CAMERA_MSG_VIDEO_FRAME:
        LOGV("recordingCallback");
        if (mRecordingCallback) {
            mRecordingCallback(dataPtr, mRecordingCallbackCookie);
        }
        break;
    case CAMERA_MSG_RAW_IMAGE:
        LOGV("rawCallback");
        if (mRawCallback) {
            mRawCallback(dataPtr, mRawCallbackCookie);
        }
        break;
    case CAMERA_MSG_COMPRESSED_IMAGE:
        LOGV("jpegCallback");
        if (mJpegCallback) {
            mJpegCallback(dataPtr, mJpegCallbackCookie);
        }
        break;
    default:
        LOGV("dataCallback(%d, %p)", msgType, dataPtr.get());
        break;
    }
}

void Camera::binderDied(const wp<IBinder>& who) {
    LOGW("ICamera died");
    if (mErrorCallback) {
        mErrorCallback(DEAD_OBJECT, mErrorCallbackCookie);
    }
}

void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
    LOGV("binderDied");
    Mutex::Autolock _l(Camera::mLock);
    Camera::mCameraService.clear();
    LOGW("Camera server died!");
}

}; // namespace android

