diff options
author | Mathias Agopian <mathias@google.com> | 2010-02-09 17:46:37 -0800 |
---|---|---|
committer | Mathias Agopian <mathias@google.com> | 2010-02-11 13:16:22 -0800 |
commit | 3cf613507f1e2f7bd932d921a6e222e426fd3be4 (patch) | |
tree | 20c9dd57e2227046ab1d6fc1185f4136c6dac12e /camera | |
parent | 988e3f0b2c74095deae580157c57935a98573052 (diff) | |
download | frameworks_av-3cf613507f1e2f7bd932d921a6e222e426fd3be4.zip frameworks_av-3cf613507f1e2f7bd932d921a6e222e426fd3be4.tar.gz frameworks_av-3cf613507f1e2f7bd932d921a6e222e426fd3be4.tar.bz2 |
split libsurfaceflinger_client and libcamera_client out of libui
Diffstat (limited to 'camera')
-rw-r--r-- | camera/Android.mk | 25 | ||||
-rw-r--r-- | camera/Camera.cpp | 359 | ||||
-rw-r--r-- | camera/CameraParameters.cpp | 369 | ||||
-rw-r--r-- | camera/ICamera.cpp | 379 | ||||
-rw-r--r-- | camera/ICameraClient.cpp | 119 | ||||
-rw-r--r-- | camera/ICameraService.cpp | 71 |
6 files changed, 1322 insertions, 0 deletions
diff --git a/camera/Android.mk b/camera/Android.mk new file mode 100644 index 0000000..03ff229 --- /dev/null +++ b/camera/Android.mk @@ -0,0 +1,25 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + Camera.cpp \ + CameraParameters.cpp \ + ICamera.cpp \ + ICameraClient.cpp \ + ICameraService.cpp + +LOCAL_SHARED_LIBRARIES := \ + libcutils \ + libutils \ + libbinder \ + libhardware \ + libsurfaceflinger_client \ + libui + +LOCAL_MODULE:= libcamera_client + +ifeq ($(TARGET_SIMULATOR),true) + LOCAL_LDLIBS += -lpthread +endif + +include $(BUILD_SHARED_LIBRARY) diff --git a/camera/Camera.cpp b/camera/Camera.cpp new file mode 100644 index 0000000..8620e71 --- /dev/null +++ b/camera/Camera.cpp @@ -0,0 +1,359 @@ +/* +** +** 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/threads.h> + +#include <binder/IServiceManager.h> +#include <binder/IMemory.h> + +#include <camera/Camera.h> +#include <camera/ICameraService.h> + +#include <surfaceflinger/Surface.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; +} + +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) { + 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"); + sp <ICamera> c = mCamera; + if (c == 0) return NO_INIT; + if (surface != 0) { + return c->setPreviewDisplay(surface->getISurface()); + } else { + LOGD("app passed NULL surface"); + return c->setPreviewDisplay(0); + } +} + +status_t Camera::setPreviewDisplay(const sp<ISurface>& surface) +{ + LOGV("setPreviewDisplay"); + if (surface == 0) { + LOGD("app passed NULL surface"); + } + sp <ICamera> c = mCamera; + if (c == 0) return NO_INIT; + return c->setPreviewDisplay(surface); +} + + +// start preview mode +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(); +} + +status_t Camera::cancelAutoFocus() +{ + LOGV("cancelAutoFocus"); + sp <ICamera> c = mCamera; + if (c == 0) return NO_INIT; + return c->cancelAutoFocus(); +} + +// 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; +} + +// send command to camera driver +status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) +{ + LOGV("sendCommand"); + sp <ICamera> c = mCamera; + if (c == 0) return NO_INIT; + return c->sendCommand(cmd, arg1, arg2); +} + +void Camera::setListener(const sp<CameraListener>& listener) +{ + Mutex::Autolock _l(mLock); + mListener = listener; +} + +void Camera::setPreviewCallbackFlags(int flag) +{ + LOGV("setPreviewCallbackFlags"); + sp <ICamera> c = mCamera; + if (c == 0) return; + mCamera->setPreviewCallbackFlag(flag); +} + +// callback from camera service +void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) +{ + sp<CameraListener> listener; + { + Mutex::Autolock _l(mLock); + listener = mListener; + } + if (listener != NULL) { + listener->notify(msgType, ext1, ext2); + } +} + +// callback from camera service when frame or image is ready +void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr) +{ + sp<CameraListener> listener; + { + Mutex::Autolock _l(mLock); + listener = mListener; + } + if (listener != NULL) { + listener->postData(msgType, dataPtr); + } +} + +// callback from camera service when timestamped frame is ready +void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) +{ + sp<CameraListener> listener; + { + Mutex::Autolock _l(mLock); + listener = mListener; + } + if (listener != NULL) { + listener->postDataTimestamp(timestamp, msgType, dataPtr); + } +} + +void Camera::binderDied(const wp<IBinder>& who) { + LOGW("ICamera died"); + notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0); +} + +void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) { + LOGV("binderDied"); + Mutex::Autolock _l(Camera::mLock); + Camera::mCameraService.clear(); + LOGW("Camera server died!"); +} + +}; // namespace android + diff --git a/camera/CameraParameters.cpp b/camera/CameraParameters.cpp new file mode 100644 index 0000000..1bf1759 --- /dev/null +++ b/camera/CameraParameters.cpp @@ -0,0 +1,369 @@ +/* +** +** 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 "CameraParams" +#include <utils/Log.h> + +#include <string.h> +#include <stdlib.h> +#include <camera/CameraParameters.h> + +namespace android { +// Parameter keys to communicate between camera application and driver. +const char CameraParameters::KEY_PREVIEW_SIZE[] = "preview-size"; +const char CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES[] = "preview-size-values"; +const char CameraParameters::KEY_PREVIEW_FORMAT[] = "preview-format"; +const char CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS[] = "preview-format-values"; +const char CameraParameters::KEY_PREVIEW_FRAME_RATE[] = "preview-frame-rate"; +const char CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES[] = "preview-frame-rate-values"; +const char CameraParameters::KEY_PICTURE_SIZE[] = "picture-size"; +const char CameraParameters::KEY_SUPPORTED_PICTURE_SIZES[] = "picture-size-values"; +const char CameraParameters::KEY_PICTURE_FORMAT[] = "picture-format"; +const char CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS[] = "picture-format-values"; +const char CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH[] = "jpeg-thumbnail-width"; +const char CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT[] = "jpeg-thumbnail-height"; +const char CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES[] = "jpeg-thumbnail-size-values"; +const char CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY[] = "jpeg-thumbnail-quality"; +const char CameraParameters::KEY_JPEG_QUALITY[] = "jpeg-quality"; +const char CameraParameters::KEY_ROTATION[] = "rotation"; +const char CameraParameters::KEY_GPS_LATITUDE[] = "gps-latitude"; +const char CameraParameters::KEY_GPS_LONGITUDE[] = "gps-longitude"; +const char CameraParameters::KEY_GPS_ALTITUDE[] = "gps-altitude"; +const char CameraParameters::KEY_GPS_TIMESTAMP[] = "gps-timestamp"; +const char CameraParameters::KEY_WHITE_BALANCE[] = "whitebalance"; +const char CameraParameters::KEY_SUPPORTED_WHITE_BALANCE[] = "whitebalance-values"; +const char CameraParameters::KEY_EFFECT[] = "effect"; +const char CameraParameters::KEY_SUPPORTED_EFFECTS[] = "effect-values"; +const char CameraParameters::KEY_ANTIBANDING[] = "antibanding"; +const char CameraParameters::KEY_SUPPORTED_ANTIBANDING[] = "antibanding-values"; +const char CameraParameters::KEY_SCENE_MODE[] = "scene-mode"; +const char CameraParameters::KEY_SUPPORTED_SCENE_MODES[] = "scene-mode-values"; +const char CameraParameters::KEY_FLASH_MODE[] = "flash-mode"; +const char CameraParameters::KEY_SUPPORTED_FLASH_MODES[] = "flash-mode-values"; +const char CameraParameters::KEY_FOCUS_MODE[] = "focus-mode"; +const char CameraParameters::KEY_SUPPORTED_FOCUS_MODES[] = "focus-mode-values"; +const char CameraParameters::KEY_FOCAL_LENGTH[] = "focal-length"; +const char CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE[] = "horizontal-view-angle"; +const char CameraParameters::KEY_VERTICAL_VIEW_ANGLE[] = "vertical-view-angle"; +const char CameraParameters::KEY_EXPOSURE_COMPENSATION[] = "exposure-compensation"; +const char CameraParameters::KEY_SUPPORTED_EXPOSURE_COMPENSATION[] = "exposure-compensation-values"; + +// Values for white balance settings. +const char CameraParameters::WHITE_BALANCE_AUTO[] = "auto"; +const char CameraParameters::WHITE_BALANCE_INCANDESCENT[] = "incandescent"; +const char CameraParameters::WHITE_BALANCE_FLUORESCENT[] = "fluorescent"; +const char CameraParameters::WHITE_BALANCE_WARM_FLUORESCENT[] = "warm-fluorescent"; +const char CameraParameters::WHITE_BALANCE_DAYLIGHT[] = "daylight"; +const char CameraParameters::WHITE_BALANCE_CLOUDY_DAYLIGHT[] = "cloudy-daylight"; +const char CameraParameters::WHITE_BALANCE_TWILIGHT[] = "twilight"; +const char CameraParameters::WHITE_BALANCE_SHADE[] = "shade"; + +// Values for effect settings. +const char CameraParameters::EFFECT_NONE[] = "none"; +const char CameraParameters::EFFECT_MONO[] = "mono"; +const char CameraParameters::EFFECT_NEGATIVE[] = "negative"; +const char CameraParameters::EFFECT_SOLARIZE[] = "solarize"; +const char CameraParameters::EFFECT_SEPIA[] = "sepia"; +const char CameraParameters::EFFECT_POSTERIZE[] = "posterize"; +const char CameraParameters::EFFECT_WHITEBOARD[] = "whiteboard"; +const char CameraParameters::EFFECT_BLACKBOARD[] = "blackboard"; +const char CameraParameters::EFFECT_AQUA[] = "aqua"; + +// Values for antibanding settings. +const char CameraParameters::ANTIBANDING_AUTO[] = "auto"; +const char CameraParameters::ANTIBANDING_50HZ[] = "50hz"; +const char CameraParameters::ANTIBANDING_60HZ[] = "60hz"; +const char CameraParameters::ANTIBANDING_OFF[] = "off"; + +// Values for flash mode settings. +const char CameraParameters::FLASH_MODE_OFF[] = "off"; +const char CameraParameters::FLASH_MODE_AUTO[] = "auto"; +const char CameraParameters::FLASH_MODE_ON[] = "on"; +const char CameraParameters::FLASH_MODE_RED_EYE[] = "red-eye"; +const char CameraParameters::FLASH_MODE_TORCH[] = "torch"; + +// Values for scene mode settings. +const char CameraParameters::SCENE_MODE_AUTO[] = "auto"; +const char CameraParameters::SCENE_MODE_ACTION[] = "action"; +const char CameraParameters::SCENE_MODE_PORTRAIT[] = "portrait"; +const char CameraParameters::SCENE_MODE_LANDSCAPE[] = "landscape"; +const char CameraParameters::SCENE_MODE_NIGHT[] = "night"; +const char CameraParameters::SCENE_MODE_NIGHT_PORTRAIT[] = "night-portrait"; +const char CameraParameters::SCENE_MODE_THEATRE[] = "theatre"; +const char CameraParameters::SCENE_MODE_BEACH[] = "beach"; +const char CameraParameters::SCENE_MODE_SNOW[] = "snow"; +const char CameraParameters::SCENE_MODE_SUNSET[] = "sunset"; +const char CameraParameters::SCENE_MODE_STEADYPHOTO[] = "steadyphoto"; +const char CameraParameters::SCENE_MODE_FIREWORKS[] = "fireworks"; +const char CameraParameters::SCENE_MODE_SPORTS[] = "sports"; +const char CameraParameters::SCENE_MODE_PARTY[] = "party"; +const char CameraParameters::SCENE_MODE_CANDLELIGHT[] = "candlelight"; + +// Formats for setPreviewFormat and setPictureFormat. +const char CameraParameters::PIXEL_FORMAT_YUV422SP[] = "yuv422sp"; +const char CameraParameters::PIXEL_FORMAT_YUV420SP[] = "yuv420sp"; +const char CameraParameters::PIXEL_FORMAT_YUV422I[] = "yuv422i-yuyv"; +const char CameraParameters::PIXEL_FORMAT_RGB565[] = "rgb565"; +const char CameraParameters::PIXEL_FORMAT_JPEG[] = "jpeg"; + +// Values for focus mode settings. +const char CameraParameters::FOCUS_MODE_AUTO[] = "auto"; +const char CameraParameters::FOCUS_MODE_INFINITY[] = "infinity"; +const char CameraParameters::FOCUS_MODE_MACRO[] = "macro"; +const char CameraParameters::FOCUS_MODE_FIXED[] = "fixed"; + +CameraParameters::CameraParameters() + : mMap() +{ +} + +CameraParameters::~CameraParameters() +{ +} + +String8 CameraParameters::flatten() const +{ + String8 flattened(""); + size_t size = mMap.size(); + + for (size_t i = 0; i < size; i++) { + String8 k, v; + k = mMap.keyAt(i); + v = mMap.valueAt(i); + + flattened += k; + flattened += "="; + flattened += v; + if (i != size-1) + flattened += ";"; + } + + return flattened; +} + +void CameraParameters::unflatten(const String8 ¶ms) +{ + const char *a = params.string(); + const char *b; + + mMap.clear(); + + for (;;) { + // Find the bounds of the key name. + b = strchr(a, '='); + if (b == 0) + break; + + // Create the key string. + String8 k(a, (size_t)(b-a)); + + // Find the value. + a = b+1; + b = strchr(a, ';'); + if (b == 0) { + // If there's no semicolon, this is the last item. + String8 v(a); + mMap.add(k, v); + break; + } + + String8 v(a, (size_t)(b-a)); + mMap.add(k, v); + a = b+1; + } +} + + +void CameraParameters::set(const char *key, const char *value) +{ + // XXX i think i can do this with strspn() + if (strchr(key, '=') || strchr(key, ';')) { + //XXX LOGE("Key \"%s\"contains invalid character (= or ;)", key); + return; + } + + if (strchr(value, '=') || strchr(key, ';')) { + //XXX LOGE("Value \"%s\"contains invalid character (= or ;)", value); + return; + } + + mMap.replaceValueFor(String8(key), String8(value)); +} + +void CameraParameters::set(const char *key, int value) +{ + char str[16]; + sprintf(str, "%d", value); + set(key, str); +} + +void CameraParameters::setFloat(const char *key, float value) +{ + char str[16]; // 14 should be enough. We overestimate to be safe. + snprintf(str, sizeof(str), "%g", value); + set(key, str); +} + +const char *CameraParameters::get(const char *key) const +{ + String8 v = mMap.valueFor(String8(key)); + if (v.length() == 0) + return 0; + return v.string(); +} + +int CameraParameters::getInt(const char *key) const +{ + const char *v = get(key); + if (v == 0) + return -1; + return strtol(v, 0, 0); +} + +float CameraParameters::getFloat(const char *key) const +{ + const char *v = get(key); + if (v == 0) return -1; + return strtof(v, 0); +} + +static int parse_size(const char *str, int &width, int &height) +{ + // Find the width. + char *end; + int w = (int)strtol(str, &end, 10); + // If an 'x' does not immediately follow, give up. + if (*end != 'x') + return -1; + + // Find the height, immediately after the 'x'. + int h = (int)strtol(end+1, 0, 10); + + width = w; + height = h; + + return 0; +} + +void CameraParameters::setPreviewSize(int width, int height) +{ + char str[32]; + sprintf(str, "%dx%d", width, height); + set(KEY_PREVIEW_SIZE, str); +} + +void CameraParameters::getPreviewSize(int *width, int *height) const +{ + *width = -1; + *height = -1; + + // Get the current string, if it doesn't exist, leave the -1x-1 + const char *p = get(KEY_PREVIEW_SIZE); + if (p == 0) + return; + + int w, h; + if (parse_size(p, w, h) == 0) { + *width = w; + *height = h; + } +} + +void CameraParameters::setPreviewFrameRate(int fps) +{ + set(KEY_PREVIEW_FRAME_RATE, fps); +} + +int CameraParameters::getPreviewFrameRate() const +{ + return getInt(KEY_PREVIEW_FRAME_RATE); +} + +void CameraParameters::setPreviewFormat(const char *format) +{ + set(KEY_PREVIEW_FORMAT, format); +} + +const char *CameraParameters::getPreviewFormat() const +{ + return get(KEY_PREVIEW_FORMAT); +} + +void CameraParameters::setPictureSize(int width, int height) +{ + char str[32]; + sprintf(str, "%dx%d", width, height); + set(KEY_PICTURE_SIZE, str); +} + +void CameraParameters::getPictureSize(int *width, int *height) const +{ + *width = -1; + *height = -1; + + // Get the current string, if it doesn't exist, leave the -1x-1 + const char *p = get(KEY_PICTURE_SIZE); + if (p == 0) + return; + + int w, h; + if (parse_size(p, w, h) == 0) { + *width = w; + *height = h; + } +} + +void CameraParameters::setPictureFormat(const char *format) +{ + set(KEY_PICTURE_FORMAT, format); +} + +const char *CameraParameters::getPictureFormat() const +{ + return get(KEY_PICTURE_FORMAT); +} + +void CameraParameters::dump() const +{ + LOGD("dump: mMap.size = %d", mMap.size()); + for (size_t i = 0; i < mMap.size(); i++) { + String8 k, v; + k = mMap.keyAt(i); + v = mMap.valueAt(i); + LOGD("%s: %s\n", k.string(), v.string()); + } +} + +status_t CameraParameters::dump(int fd, const Vector<String16>& args) const +{ + const size_t SIZE = 256; + char buffer[SIZE]; + String8 result; + snprintf(buffer, 255, "CameraParameters::dump: mMap.size = %d\n", mMap.size()); + result.append(buffer); + for (size_t i = 0; i < mMap.size(); i++) { + String8 k, v; + k = mMap.keyAt(i); + v = mMap.valueAt(i); + snprintf(buffer, 255, "\t%s: %s\n", k.string(), v.string()); + result.append(buffer); + } + write(fd, result.string(), result.size()); + return NO_ERROR; +} + +}; // namespace android diff --git a/camera/ICamera.cpp b/camera/ICamera.cpp new file mode 100644 index 0000000..724bd20 --- /dev/null +++ b/camera/ICamera.cpp @@ -0,0 +1,379 @@ +/* +** +** 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_NDEBUG 0 +#define LOG_TAG "ICamera" +#include <utils/Log.h> +#include <stdint.h> +#include <sys/types.h> +#include <binder/Parcel.h> +#include <camera/ICamera.h> + +namespace android { + +enum { + DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, + SET_PREVIEW_DISPLAY, + SET_PREVIEW_CALLBACK_FLAG, + START_PREVIEW, + STOP_PREVIEW, + AUTO_FOCUS, + CANCEL_AUTO_FOCUS, + TAKE_PICTURE, + SET_PARAMETERS, + GET_PARAMETERS, + SEND_COMMAND, + CONNECT, + LOCK, + UNLOCK, + PREVIEW_ENABLED, + START_RECORDING, + STOP_RECORDING, + RECORDING_ENABLED, + RELEASE_RECORDING_FRAME, +}; + +class BpCamera: public BpInterface<ICamera> +{ +public: + BpCamera(const sp<IBinder>& impl) + : BpInterface<ICamera>(impl) + { + } + + // disconnect from camera service + void disconnect() + { + LOGV("disconnect"); + Parcel data, reply; + data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + remote()->transact(DISCONNECT, data, &reply); + } + + // pass the buffered ISurface to the camera service + status_t setPreviewDisplay(const sp<ISurface>& surface) + { + LOGV("setPreviewDisplay"); + Parcel data, reply; + data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + data.writeStrongBinder(surface->asBinder()); + remote()->transact(SET_PREVIEW_DISPLAY, data, &reply); + return reply.readInt32(); + } + + // set the preview callback flag to affect how the received frames from + // preview are handled. See Camera.h for details. + void setPreviewCallbackFlag(int flag) + { + LOGV("setPreviewCallbackFlag(%d)", flag); + Parcel data, reply; + data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + data.writeInt32(flag); + remote()->transact(SET_PREVIEW_CALLBACK_FLAG, data, &reply); + } + + // start preview mode, must call setPreviewDisplay first + status_t startPreview() + { + LOGV("startPreview"); + Parcel data, reply; + data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + remote()->transact(START_PREVIEW, data, &reply); + return reply.readInt32(); + } + + // start recording mode, must call setPreviewDisplay first + status_t startRecording() + { + LOGV("startRecording"); + Parcel data, reply; + data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + remote()->transact(START_RECORDING, data, &reply); + return reply.readInt32(); + } + + // stop preview mode + void stopPreview() + { + LOGV("stopPreview"); + Parcel data, reply; + data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + remote()->transact(STOP_PREVIEW, data, &reply); + } + + // stop recording mode + void stopRecording() + { + LOGV("stopRecording"); + Parcel data, reply; + data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + remote()->transact(STOP_RECORDING, data, &reply); + } + + void releaseRecordingFrame(const sp<IMemory>& mem) + { + LOGV("releaseRecordingFrame"); + Parcel data, reply; + data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + data.writeStrongBinder(mem->asBinder()); + remote()->transact(RELEASE_RECORDING_FRAME, data, &reply); + } + + // check preview state + bool previewEnabled() + { + LOGV("previewEnabled"); + Parcel data, reply; + data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + remote()->transact(PREVIEW_ENABLED, data, &reply); + return reply.readInt32(); + } + + // check recording state + bool recordingEnabled() + { + LOGV("recordingEnabled"); + Parcel data, reply; + data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + remote()->transact(RECORDING_ENABLED, data, &reply); + return reply.readInt32(); + } + + // auto focus + status_t autoFocus() + { + LOGV("autoFocus"); + Parcel data, reply; + data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + remote()->transact(AUTO_FOCUS, data, &reply); + status_t ret = reply.readInt32(); + return ret; + } + + // cancel focus + status_t cancelAutoFocus() + { + LOGV("cancelAutoFocus"); + Parcel data, reply; + data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + remote()->transact(CANCEL_AUTO_FOCUS, data, &reply); + status_t ret = reply.readInt32(); + return ret; + } + + // take a picture - returns an IMemory (ref-counted mmap) + status_t takePicture() + { + LOGV("takePicture"); + Parcel data, reply; + data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + remote()->transact(TAKE_PICTURE, data, &reply); + status_t ret = reply.readInt32(); + return ret; + } + + // set preview/capture parameters - key/value pairs + status_t setParameters(const String8& params) + { + LOGV("setParameters"); + Parcel data, reply; + data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + data.writeString8(params); + remote()->transact(SET_PARAMETERS, data, &reply); + return reply.readInt32(); + } + + // get preview/capture parameters - key/value pairs + String8 getParameters() const + { + LOGV("getParameters"); + Parcel data, reply; + data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + remote()->transact(GET_PARAMETERS, data, &reply); + return reply.readString8(); + } + virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) + { + LOGD("sendCommand"); + Parcel data, reply; + data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + data.writeInt32(cmd); + data.writeInt32(arg1); + data.writeInt32(arg2); + remote()->transact(SEND_COMMAND, data, &reply); + return reply.readInt32(); + } + virtual status_t connect(const sp<ICameraClient>& cameraClient) + { + Parcel data, reply; + data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + data.writeStrongBinder(cameraClient->asBinder()); + remote()->transact(CONNECT, data, &reply); + return reply.readInt32(); + } + virtual status_t lock() + { + Parcel data, reply; + data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + remote()->transact(LOCK, data, &reply); + return reply.readInt32(); + } + virtual status_t unlock() + { + Parcel data, reply; + data.writeInterfaceToken(ICamera::getInterfaceDescriptor()); + remote()->transact(UNLOCK, data, &reply); + return reply.readInt32(); + } +}; + +IMPLEMENT_META_INTERFACE(Camera, "android.hardware.ICamera"); + +// ---------------------------------------------------------------------- + +status_t BnCamera::onTransact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) +{ + switch(code) { + case DISCONNECT: { + LOGV("DISCONNECT"); + CHECK_INTERFACE(ICamera, data, reply); + disconnect(); + return NO_ERROR; + } break; + case SET_PREVIEW_DISPLAY: { + LOGV("SET_PREVIEW_DISPLAY"); + CHECK_INTERFACE(ICamera, data, reply); + sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder()); + reply->writeInt32(setPreviewDisplay(surface)); + return NO_ERROR; + } break; + case SET_PREVIEW_CALLBACK_FLAG: { + LOGV("SET_PREVIEW_CALLBACK_TYPE"); + CHECK_INTERFACE(ICamera, data, reply); + int callback_flag = data.readInt32(); + setPreviewCallbackFlag(callback_flag); + return NO_ERROR; + } break; + case START_PREVIEW: { + LOGV("START_PREVIEW"); + CHECK_INTERFACE(ICamera, data, reply); + reply->writeInt32(startPreview()); + return NO_ERROR; + } break; + case START_RECORDING: { + LOGV("START_RECORDING"); + CHECK_INTERFACE(ICamera, data, reply); + reply->writeInt32(startRecording()); + return NO_ERROR; + } break; + case STOP_PREVIEW: { + LOGV("STOP_PREVIEW"); + CHECK_INTERFACE(ICamera, data, reply); + stopPreview(); + return NO_ERROR; + } break; + case STOP_RECORDING: { + LOGV("STOP_RECORDING"); + CHECK_INTERFACE(ICamera, data, reply); + stopRecording(); + return NO_ERROR; + } break; + case RELEASE_RECORDING_FRAME: { + LOGV("RELEASE_RECORDING_FRAME"); + CHECK_INTERFACE(ICamera, data, reply); + sp<IMemory> mem = interface_cast<IMemory>(data.readStrongBinder()); + releaseRecordingFrame(mem); + return NO_ERROR; + } break; + case PREVIEW_ENABLED: { + LOGV("PREVIEW_ENABLED"); + CHECK_INTERFACE(ICamera, data, reply); + reply->writeInt32(previewEnabled()); + return NO_ERROR; + } break; + case RECORDING_ENABLED: { + LOGV("RECORDING_ENABLED"); + CHECK_INTERFACE(ICamera, data, reply); + reply->writeInt32(recordingEnabled()); + return NO_ERROR; + } break; + case AUTO_FOCUS: { + LOGV("AUTO_FOCUS"); + CHECK_INTERFACE(ICamera, data, reply); + reply->writeInt32(autoFocus()); + return NO_ERROR; + } break; + case CANCEL_AUTO_FOCUS: { + LOGV("CANCEL_AUTO_FOCUS"); + CHECK_INTERFACE(ICamera, data, reply); + reply->writeInt32(cancelAutoFocus()); + return NO_ERROR; + } break; + case TAKE_PICTURE: { + LOGV("TAKE_PICTURE"); + CHECK_INTERFACE(ICamera, data, reply); + reply->writeInt32(takePicture()); + return NO_ERROR; + } break; + case SET_PARAMETERS: { + LOGV("SET_PARAMETERS"); + CHECK_INTERFACE(ICamera, data, reply); + String8 params(data.readString8()); + reply->writeInt32(setParameters(params)); + return NO_ERROR; + } break; + case GET_PARAMETERS: { + LOGV("GET_PARAMETERS"); + CHECK_INTERFACE(ICamera, data, reply); + reply->writeString8(getParameters()); + return NO_ERROR; + } break; + case SEND_COMMAND: { + LOGV("SEND_COMMAND"); + CHECK_INTERFACE(ICamera, data, reply); + int command = data.readInt32(); + int arg1 = data.readInt32(); + int arg2 = data.readInt32(); + reply->writeInt32(sendCommand(command, arg1, arg2)); + return NO_ERROR; + } break; + case CONNECT: { + CHECK_INTERFACE(ICamera, data, reply); + sp<ICameraClient> cameraClient = interface_cast<ICameraClient>(data.readStrongBinder()); + reply->writeInt32(connect(cameraClient)); + return NO_ERROR; + } break; + case LOCK: { + CHECK_INTERFACE(ICamera, data, reply); + reply->writeInt32(lock()); + return NO_ERROR; + } break; + case UNLOCK: { + CHECK_INTERFACE(ICamera, data, reply); + reply->writeInt32(unlock()); + return NO_ERROR; + } break; + default: + return BBinder::onTransact(code, data, reply, flags); + } +} + +// ---------------------------------------------------------------------------- + +}; // namespace android + diff --git a/camera/ICameraClient.cpp b/camera/ICameraClient.cpp new file mode 100644 index 0000000..cb3bd0c --- /dev/null +++ b/camera/ICameraClient.cpp @@ -0,0 +1,119 @@ +/* +** +** 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_NDEBUG 0 +#define LOG_TAG "ICameraClient" +#include <utils/Log.h> +#include <stdint.h> +#include <sys/types.h> +#include <camera/ICameraClient.h> + +namespace android { + +enum { + NOTIFY_CALLBACK = IBinder::FIRST_CALL_TRANSACTION, + DATA_CALLBACK, + DATA_CALLBACK_TIMESTAMP, +}; + +class BpCameraClient: public BpInterface<ICameraClient> +{ +public: + BpCameraClient(const sp<IBinder>& impl) + : BpInterface<ICameraClient>(impl) + { + } + + // generic callback from camera service to app + void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) + { + LOGV("notifyCallback"); + Parcel data, reply; + data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor()); + data.writeInt32(msgType); + data.writeInt32(ext1); + data.writeInt32(ext2); + remote()->transact(NOTIFY_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY); + } + + // generic data callback from camera service to app with image data + void dataCallback(int32_t msgType, const sp<IMemory>& imageData) + { + LOGV("dataCallback"); + Parcel data, reply; + data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor()); + data.writeInt32(msgType); + data.writeStrongBinder(imageData->asBinder()); + remote()->transact(DATA_CALLBACK, data, &reply, IBinder::FLAG_ONEWAY); + } + + // generic data callback from camera service to app with image data + void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& imageData) + { + LOGV("dataCallback"); + Parcel data, reply; + data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor()); + data.writeInt64(timestamp); + data.writeInt32(msgType); + data.writeStrongBinder(imageData->asBinder()); + remote()->transact(DATA_CALLBACK_TIMESTAMP, data, &reply, IBinder::FLAG_ONEWAY); + } +}; + +IMPLEMENT_META_INTERFACE(CameraClient, "android.hardware.ICameraClient"); + +// ---------------------------------------------------------------------- + +status_t BnCameraClient::onTransact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) +{ + switch(code) { + case NOTIFY_CALLBACK: { + LOGV("NOTIFY_CALLBACK"); + CHECK_INTERFACE(ICameraClient, data, reply); + int32_t msgType = data.readInt32(); + int32_t ext1 = data.readInt32(); + int32_t ext2 = data.readInt32(); + notifyCallback(msgType, ext1, ext2); + return NO_ERROR; + } break; + case DATA_CALLBACK: { + LOGV("DATA_CALLBACK"); + CHECK_INTERFACE(ICameraClient, data, reply); + int32_t msgType = data.readInt32(); + sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder()); + dataCallback(msgType, imageData); + return NO_ERROR; + } break; + case DATA_CALLBACK_TIMESTAMP: { + LOGV("DATA_CALLBACK_TIMESTAMP"); + CHECK_INTERFACE(ICameraClient, data, reply); + nsecs_t timestamp = data.readInt64(); + int32_t msgType = data.readInt32(); + sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder()); + dataCallbackTimestamp(timestamp, msgType, imageData); + return NO_ERROR; + } break; + default: + return BBinder::onTransact(code, data, reply, flags); + } +} + +// ---------------------------------------------------------------------------- + +}; // namespace android + diff --git a/camera/ICameraService.cpp b/camera/ICameraService.cpp new file mode 100644 index 0000000..46b5478 --- /dev/null +++ b/camera/ICameraService.cpp @@ -0,0 +1,71 @@ +/* +** +** 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. +*/ + +#include <stdint.h> +#include <sys/types.h> + +#include <binder/Parcel.h> +#include <binder/IPCThreadState.h> +#include <binder/IServiceManager.h> + +#include <camera/ICameraService.h> + +namespace android { + +class BpCameraService: public BpInterface<ICameraService> +{ +public: + BpCameraService(const sp<IBinder>& impl) + : BpInterface<ICameraService>(impl) + { + } + + // connect to camera service + virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient) + { + Parcel data, reply; + data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); + data.writeStrongBinder(cameraClient->asBinder()); + remote()->transact(BnCameraService::CONNECT, data, &reply); + return interface_cast<ICamera>(reply.readStrongBinder()); + } +}; + +IMPLEMENT_META_INTERFACE(CameraService, "android.hardware.ICameraService"); + +// ---------------------------------------------------------------------- + +status_t BnCameraService::onTransact( + uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) +{ + switch(code) { + case CONNECT: { + CHECK_INTERFACE(ICameraService, data, reply); + sp<ICameraClient> cameraClient = interface_cast<ICameraClient>(data.readStrongBinder()); + sp<ICamera> camera = connect(cameraClient); + reply->writeStrongBinder(camera->asBinder()); + return NO_ERROR; + } break; + default: + return BBinder::onTransact(code, data, reply, flags); + } +} + +// ---------------------------------------------------------------------------- + +}; // namespace android + |