summaryrefslogtreecommitdiffstats
path: root/libs/ui/Camera.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ui/Camera.cpp')
-rw-r--r--libs/ui/Camera.cpp249
1 files changed, 249 insertions, 0 deletions
diff --git a/libs/ui/Camera.cpp b/libs/ui/Camera.cpp
new file mode 100644
index 0000000..1528e6e
--- /dev/null
+++ b/libs/ui/Camera.cpp
@@ -0,0 +1,249 @@
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** 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_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()
+ : mStatus(UNKNOWN_ERROR),
+ mShutterCallback(0),
+ mShutterCallbackCookie(0),
+ mRawCallback(0),
+ mRawCallbackCookie(0),
+ mJpegCallback(0),
+ mJpegCallbackCookie(0),
+ mFrameCallback(0),
+ mFrameCallbackCookie(0),
+ mErrorCallback(0),
+ mErrorCallbackCookie(0),
+ mAutoFocusCallback(0),
+ mAutoFocusCallbackCookie(0)
+{
+}
+
+Camera::~Camera()
+{
+ disconnect();
+}
+
+sp<Camera> Camera::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;
+ }
+ return c;
+}
+
+void Camera::disconnect()
+{
+ if (mCamera != 0) {
+ mErrorCallback = 0;
+ mCamera->disconnect();
+ mCamera = 0;
+ }
+}
+
+// pass the buffered ISurface to the camera service
+status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
+{
+ if (surface == 0) {
+ LOGE("app passed NULL surface");
+ return NO_INIT;
+ }
+ return mCamera->setPreviewDisplay(surface->getISurface());
+}
+
+// start preview mode, must call setPreviewDisplay first
+status_t Camera::startPreview()
+{
+ return mCamera->startPreview();
+}
+
+// stop preview mode
+void Camera::stopPreview()
+{
+ mCamera->stopPreview();
+}
+
+status_t Camera::autoFocus()
+{
+ return mCamera->autoFocus();
+}
+
+// take a picture
+status_t Camera::takePicture()
+{
+ return mCamera->takePicture();
+}
+
+// set preview/capture parameters - key/value pairs
+status_t Camera::setParameters(const String8& params)
+{
+ return mCamera->setParameters(params);
+}
+
+// get preview/capture parameters - key/value pairs
+String8 Camera::getParameters() const
+{
+ String8 params = mCamera->getParameters();
+ return params;
+}
+
+void Camera::setAutoFocusCallback(autofocus_callback cb, void *cookie)
+{
+ mAutoFocusCallback = cb;
+ mAutoFocusCallbackCookie = cookie;
+}
+
+void Camera::setShutterCallback(shutter_callback cb, void *cookie)
+{
+ mShutterCallback = cb;
+ mShutterCallbackCookie = cookie;
+}
+
+void Camera::setRawCallback(frame_callback cb, void *cookie)
+{
+ mRawCallback = cb;
+ mRawCallbackCookie = cookie;
+}
+
+void Camera::setJpegCallback(frame_callback cb, void *cookie)
+{
+ mJpegCallback = cb;
+ mJpegCallbackCookie = cookie;
+}
+
+void Camera::setFrameCallback(frame_callback cb, void *cookie)
+{
+ mFrameCallback = cb;
+ mFrameCallbackCookie = cookie;
+ mCamera->setHasFrameCallback(cb != NULL);
+}
+
+void Camera::setErrorCallback(error_callback cb, void *cookie)
+{
+ mErrorCallback = cb;
+ mErrorCallbackCookie = cookie;
+}
+
+void Camera::autoFocusCallback(bool focused)
+{
+ if (mAutoFocusCallback) {
+ mAutoFocusCallback(focused, mAutoFocusCallbackCookie);
+ }
+}
+
+void Camera::shutterCallback()
+{
+ if (mShutterCallback) {
+ mShutterCallback(mShutterCallbackCookie);
+ }
+}
+
+void Camera::rawCallback(const sp<IMemory>& picture)
+{
+ if (mRawCallback) {
+ mRawCallback(picture, mRawCallbackCookie);
+ }
+}
+
+// callback from camera service when image is ready
+void Camera::jpegCallback(const sp<IMemory>& picture)
+{
+ if (mJpegCallback) {
+ mJpegCallback(picture, mJpegCallbackCookie);
+ }
+}
+
+// callback from camera service when video frame is ready
+void Camera::frameCallback(const sp<IMemory>& frame)
+{
+ if (mFrameCallback) {
+ mFrameCallback(frame, mFrameCallbackCookie);
+ }
+}
+
+// callback from camera service when an error occurs in preview or takePicture
+void Camera::errorCallback(status_t error)
+{
+ if (mErrorCallback) {
+ mErrorCallback(error, mErrorCallbackCookie);
+ }
+}
+
+void Camera::binderDied(const wp<IBinder>& who) {
+ LOGW("ICamera died");
+ if (mErrorCallback) {
+ mErrorCallback(DEAD_OBJECT, mErrorCallbackCookie);
+ }
+}
+
+void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
+ Mutex::Autolock _l(Camera::mLock);
+ Camera::mCameraService.clear();
+ LOGW("Camera server died!");
+}
+
+}; // namespace android
+