replicant-frameworks_native/libs/ui/Camera.cpp
Dave Sparks 93b94584ed Modify camera framework to use new streamlined binder interface.
This is the second half of bug 1837832. Modifies the camera client
and camera service to use the new binder interface. Removes the
old binder interface. There will be one more part to this change
to surface the undefined callbacks to the Java layer so that
partners can implement new features without having to touch the
stack.
2009-05-11 07:36:58 -07:00

418 lines
9.8 KiB
C++

/*
**
** 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 <utils/IServiceManager.h>
#include <utils/threads.h>
#include <utils/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