diff options
author | Iliyan Malchev <malchev@google.com> | 2011-04-14 16:55:59 -0700 |
---|---|---|
committer | Iliyan Malchev <malchev@google.com> | 2011-05-03 15:49:40 -0700 |
commit | 8951a97b1f8462c37e740ea5082eea0445d2c501 (patch) | |
tree | 8817cddc9d87a872846d4b576bdb96310fa2bd01 /services | |
parent | 9e626526453f91999bdf3de4c2ec8e55c5d90511 (diff) | |
download | frameworks_av-8951a97b1f8462c37e740ea5082eea0445d2c501.zip frameworks_av-8951a97b1f8462c37e740ea5082eea0445d2c501.tar.gz frameworks_av-8951a97b1f8462c37e740ea5082eea0445d2c501.tar.bz2 |
frameworks/base: switch CameraService to a HAL module
This patch changes CameraService to load a camera HAL module, instead of
linking directly against a library that implements the CameraHardwareInterface
class.
CameraHardwareInterface no longer defines the API to the camera HAL. Instead,
this is now in HAL header hardware/camera.h. We keep CamerHardwareInterface as
a class local to CameraService, which wraps around the new HAL calls. In the
future, we may remove this class entirely and have CameraService call the HAL
methods directly.
Change-Id: I5c61ac40078fc0b50bbac5881a556fe6c8837641
Signed-off-by: Iliyan Malchev <malchev@google.com>
Diffstat (limited to 'services')
-rw-r--r-- | services/camera/libcameraservice/Android.mk | 46 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraHardwareInterface.h | 619 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraService.cpp | 70 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraService.h | 7 |
4 files changed, 675 insertions, 67 deletions
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk index 14f1e8b..e35435e 100644 --- a/services/camera/libcameraservice/Android.mk +++ b/services/camera/libcameraservice/Android.mk @@ -1,38 +1,5 @@ LOCAL_PATH:= $(call my-dir) -# Set USE_CAMERA_STUB if you don't want to use the hardware camera. - -# force these builds to use camera stub only -ifneq ($(filter sooner generic sim,$(TARGET_DEVICE)),) - USE_CAMERA_STUB:=true -endif - -ifeq ($(USE_CAMERA_STUB),) - USE_CAMERA_STUB:=false -endif - -ifeq ($(USE_CAMERA_STUB),true) -# -# libcamerastub -# - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - CameraHardwareStub.cpp \ - FakeCamera.cpp - -LOCAL_MODULE:= libcamerastub - -ifeq ($(TARGET_SIMULATOR),true) -LOCAL_CFLAGS += -DSINGLE_PROCESS -endif - -LOCAL_SHARED_LIBRARIES:= libui - -include $(BUILD_STATIC_LIBRARY) -endif # USE_CAMERA_STUB - # # libcameraservice # @@ -49,18 +16,9 @@ LOCAL_SHARED_LIBRARIES:= \ libcutils \ libmedia \ libcamera_client \ - libgui + libgui \ + libhardware LOCAL_MODULE:= libcameraservice -ifeq ($(TARGET_SIMULATOR),true) -LOCAL_CFLAGS += -DSINGLE_PROCESS -endif - -ifeq ($(USE_CAMERA_STUB), true) -LOCAL_STATIC_LIBRARIES += libcamerastub -else -LOCAL_SHARED_LIBRARIES += libcamera -endif - include $(BUILD_SHARED_LIBRARY) diff --git a/services/camera/libcameraservice/CameraHardwareInterface.h b/services/camera/libcameraservice/CameraHardwareInterface.h new file mode 100644 index 0000000..e30f7bf --- /dev/null +++ b/services/camera/libcameraservice/CameraHardwareInterface.h @@ -0,0 +1,619 @@ +/* + * Copyright (C) 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. + */ + +#ifndef ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H +#define ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H + +#include <binder/IMemory.h> +#include <binder/MemoryBase.h> +#include <binder/MemoryHeapBase.h> +#include <utils/RefBase.h> +#include <surfaceflinger/ISurface.h> +#include <ui/android_native_buffer.h> +#include <ui/GraphicBuffer.h> +#include <camera/Camera.h> +#include <camera/CameraParameters.h> +#include <system/window.h> +#include <hardware/camera.h> + +namespace android { + +typedef void (*notify_callback)(int32_t msgType, + int32_t ext1, + int32_t ext2, + void* user); + +typedef void (*data_callback)(int32_t msgType, + const sp<IMemory> &dataPtr, + void* user); + +typedef void (*data_callback_timestamp)(nsecs_t timestamp, + int32_t msgType, + const sp<IMemory> &dataPtr, + void *user); + +/** + * CameraHardwareInterface.h defines the interface to the + * camera hardware abstraction layer, used for setting and getting + * parameters, live previewing, and taking pictures. + * + * It is a referenced counted interface with RefBase as its base class. + * CameraService calls openCameraHardware() to retrieve a strong pointer to the + * instance of this interface and may be called multiple times. The + * following steps describe a typical sequence: + * + * -# After CameraService calls openCameraHardware(), getParameters() and + * setParameters() are used to initialize the camera instance. + * CameraService calls getPreviewHeap() to establish access to the + * preview heap so it can be registered with SurfaceFlinger for + * efficient display updating while in preview mode. + * -# startPreview() is called. The camera instance then periodically + * sends the message CAMERA_MSG_PREVIEW_FRAME (if enabled) each time + * a new preview frame is available. If data callback code needs to use + * this memory after returning, it must copy the data. + * + * Prior to taking a picture, CameraService calls autofocus(). When auto + * focusing has completed, the camera instance sends a CAMERA_MSG_FOCUS notification, + * which informs the application whether focusing was successful. The camera instance + * only sends this message once and it is up to the application to call autoFocus() + * again if refocusing is desired. + * + * CameraService calls takePicture() to request the camera instance take a + * picture. At this point, if a shutter, postview, raw, and/or compressed callback + * is desired, the corresponding message must be enabled. As with CAMERA_MSG_PREVIEW_FRAME, + * any memory provided in a data callback must be copied if it's needed after returning. + */ + +class CameraHardwareInterface : public virtual RefBase { +public: + CameraHardwareInterface(hw_module_t *module, const char *name) + { + mDevice = 0; + mName = name; + LOGI("Opening camera %s, this %p", name, this); + int rc = module->methods->open(module, name, + (hw_device_t **)&mDevice); + if (rc != OK) + LOGE("Could not open camera %s: %d", name, rc); + initHalPreviewWindow(); + } + + ~CameraHardwareInterface() + { + LOGI("Destroying camera %s", mName.string()); + int rc = mDevice->common.close(&mDevice->common); + if (rc != OK) + LOGE("Could not close camera %s: %d", mName.string(), rc); + } + + /** Set the ANativeWindow to which preview frames are sent */ + status_t setPreviewWindow(const sp<ANativeWindow>& buf) + { + LOGV("%s(%s) buf %p", __FUNCTION__, mName.string(), buf.get()); + + if (mDevice->ops->set_preview_window) { + mPreviewWindow = buf; + mHalPreviewWindow.user = this; + LOGV("%s &mHalPreviewWindow %p mHalPreviewWindow.user %p", __FUNCTION__, + &mHalPreviewWindow, mHalPreviewWindow.user); + return mDevice->ops->set_preview_window(mDevice, + buf.get() ? &mHalPreviewWindow.nw : 0); + } + return INVALID_OPERATION; + } + + /** Set the notification and data callbacks */ + void setCallbacks(notify_callback notify_cb, + data_callback data_cb, + data_callback_timestamp data_cb_timestamp, + void* user) + { + mNotifyCb = notify_cb; + mDataCb = data_cb; + mDataCbTimestamp = data_cb_timestamp; + mCbUser = user; + + LOGV("%s(%s)", __FUNCTION__, mName.string()); + + if (mDevice->ops->set_callbacks) { + mDevice->ops->set_callbacks(mDevice, + __notify_cb, + __data_cb, + __data_cb_timestamp, + __get_memory, + this); + } + } + + /** + * The following three functions all take a msgtype, + * which is a bitmask of the messages defined in + * include/ui/Camera.h + */ + + /** + * Enable a message, or set of messages. + */ + void enableMsgType(int32_t msgType) + { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + if (mDevice->ops->enable_msg_type) + mDevice->ops->enable_msg_type(mDevice, msgType); + } + + /** + * Disable a message, or a set of messages. + * + * Once received a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), camera hal + * should not rely on its client to call releaseRecordingFrame() to release + * video recording frames sent out by the cameral hal before and after the + * disableMsgType(CAMERA_MSG_VIDEO_FRAME) call. Camera hal clients must not + * modify/access any video recording frame after calling + * disableMsgType(CAMERA_MSG_VIDEO_FRAME). + */ + void disableMsgType(int32_t msgType) + { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + if (mDevice->ops->disable_msg_type) + mDevice->ops->disable_msg_type(mDevice, msgType); + } + + /** + * Query whether a message, or a set of messages, is enabled. + * Note that this is operates as an AND, if any of the messages + * queried are off, this will return false. + */ + int msgTypeEnabled(int32_t msgType) + { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + if (mDevice->ops->msg_type_enabled) + return mDevice->ops->msg_type_enabled(mDevice, msgType); + return false; + } + + /** + * Start preview mode. + */ + status_t startPreview() + { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + if (mDevice->ops->start_preview) + return mDevice->ops->start_preview(mDevice); + return INVALID_OPERATION; + } + + /** + * Stop a previously started preview. + */ + void stopPreview() + { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + if (mDevice->ops->stop_preview) + mDevice->ops->stop_preview(mDevice); + } + + /** + * Returns true if preview is enabled. + */ + int previewEnabled() + { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + if (mDevice->ops->preview_enabled) + return mDevice->ops->preview_enabled(mDevice); + return false; + } + + /** + * Request the camera hal to store meta data or real YUV data in + * the video buffers send out via CAMERA_MSG_VIDEO_FRRAME for a + * recording session. If it is not called, the default camera + * hal behavior is to store real YUV data in the video buffers. + * + * This method should be called before startRecording() in order + * to be effective. + * + * If meta data is stored in the video buffers, it is up to the + * receiver of the video buffers to interpret the contents and + * to find the actual frame data with the help of the meta data + * in the buffer. How this is done is outside of the scope of + * this method. + * + * Some camera hal may not support storing meta data in the video + * buffers, but all camera hal should support storing real YUV data + * in the video buffers. If the camera hal does not support storing + * the meta data in the video buffers when it is requested to do + * do, INVALID_OPERATION must be returned. It is very useful for + * the camera hal to pass meta data rather than the actual frame + * data directly to the video encoder, since the amount of the + * uncompressed frame data can be very large if video size is large. + * + * @param enable if true to instruct the camera hal to store + * meta data in the video buffers; false to instruct + * the camera hal to store real YUV data in the video + * buffers. + * + * @return OK on success. + */ + + status_t storeMetaDataInBuffers(int enable) + { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + if (mDevice->ops->store_meta_data_in_buffers) + return mDevice->ops->store_meta_data_in_buffers(mDevice, enable); + return enable ? INVALID_OPERATION: OK; + } + + /** + * Start record mode. When a record image is available a CAMERA_MSG_VIDEO_FRAME + * message is sent with the corresponding frame. Every record frame must be released + * by a cameral hal client via releaseRecordingFrame() before the client calls + * disableMsgType(CAMERA_MSG_VIDEO_FRAME). After the client calls + * disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's responsibility + * to manage the life-cycle of the video recording frames, and the client must + * not modify/access any video recording frames. + */ + status_t startRecording() + { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + if (mDevice->ops->start_recording) + return mDevice->ops->start_recording(mDevice); + return INVALID_OPERATION; + } + + /** + * Stop a previously started recording. + */ + void stopRecording() + { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + if (mDevice->ops->stop_recording) + mDevice->ops->stop_recording(mDevice); + } + + /** + * Returns true if recording is enabled. + */ + int recordingEnabled() + { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + if (mDevice->ops->recording_enabled) + return mDevice->ops->recording_enabled(mDevice); + return false; + } + + /** + * Release a record frame previously returned by CAMERA_MSG_VIDEO_FRAME. + * + * It is camera hal client's responsibility to release video recording + * frames sent out by the camera hal before the camera hal receives + * a call to disableMsgType(CAMERA_MSG_VIDEO_FRAME). After it receives + * the call to disableMsgType(CAMERA_MSG_VIDEO_FRAME), it is camera hal's + * responsibility of managing the life-cycle of the video recording + * frames. + */ + void releaseRecordingFrame(const sp<IMemory>& mem) + { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + if (mDevice->ops->release_recording_frame) { + ssize_t offset; + size_t size; + sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); + void *data = ((uint8_t *)heap->base()) + offset; + return mDevice->ops->release_recording_frame(mDevice, data); + } + } + + /** + * Start auto focus, the notification callback routine is called + * with CAMERA_MSG_FOCUS once when focusing is complete. autoFocus() + * will be called again if another auto focus is needed. + */ + status_t autoFocus() + { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + if (mDevice->ops->auto_focus) + return mDevice->ops->auto_focus(mDevice); + return INVALID_OPERATION; + } + + /** + * Cancels auto-focus function. If the auto-focus is still in progress, + * this function will cancel it. Whether the auto-focus is in progress + * or not, this function will return the focus position to the default. + * If the camera does not support auto-focus, this is a no-op. + */ + status_t cancelAutoFocus() + { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + if (mDevice->ops->cancel_auto_focus) + return mDevice->ops->cancel_auto_focus(mDevice); + return INVALID_OPERATION; + } + + /** + * Take a picture. + */ + status_t takePicture() + { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + if (mDevice->ops->take_picture) + return mDevice->ops->take_picture(mDevice); + return INVALID_OPERATION; + } + + /** + * Cancel a picture that was started with takePicture. Calling this + * method when no picture is being taken is a no-op. + */ + status_t cancelPicture() + { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + if (mDevice->ops->cancel_picture) + return mDevice->ops->cancel_picture(mDevice); + return INVALID_OPERATION; + } + + /** + * Set the camera parameters. This returns BAD_VALUE if any parameter is + * invalid or not supported. */ + status_t setParameters(const CameraParameters ¶ms) + { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + if (mDevice->ops->set_parameters) + return mDevice->ops->set_parameters(mDevice, + params.flatten().string()); + return INVALID_OPERATION; + } + + /** Return the camera parameters. */ + CameraParameters getParameters() const + { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + CameraParameters parms; + if (mDevice->ops->get_parameters) { + char *temp = mDevice->ops->get_parameters(mDevice); + String8 str_parms(temp); + free(temp); + parms.unflatten(str_parms); + } + return parms; + } + + /** + * Send command to camera driver. + */ + status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) + { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + if (mDevice->ops->send_command) + return mDevice->ops->send_command(mDevice, cmd, arg1, arg2); + return INVALID_OPERATION; + } + + /** + * Release the hardware resources owned by this object. Note that this is + * *not* done in the destructor. + */ + void release() { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + if (mDevice->ops->release) + mDevice->ops->release(mDevice); + } + + /** + * Dump state of the camera hardware + */ + status_t dump(int fd, const Vector<String16>& args) const + { + LOGV("%s(%s)", __FUNCTION__, mName.string()); + if (mDevice->ops->dump) + return mDevice->ops->dump(mDevice, fd); + return OK; // It's fine if the HAL doesn't implement dump() + } + +private: + camera_device_t *mDevice; + String8 mName; + + static void __notify_cb(int32_t msg_type, int32_t ext1, + int32_t ext2, void *user) + { + LOGV("%s", __FUNCTION__); + CameraHardwareInterface *__this = + static_cast<CameraHardwareInterface *>(user); + __this->mNotifyCb(msg_type, ext1, ext2, __this->mCbUser); + } + + static void __data_cb(int32_t msg_type, + const camera_memory_t *data, + void *user) + { + LOGV("%s", __FUNCTION__); + CameraHardwareInterface *__this = + static_cast<CameraHardwareInterface *>(user); + sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle)); + __this->mDataCb(msg_type, mem, __this->mCbUser); + } + + static void __data_cb_timestamp(nsecs_t timestamp, int32_t msg_type, + const camera_memory_t *data, + void *user) + { + LOGV("%s", __FUNCTION__); + CameraHardwareInterface *__this = + static_cast<CameraHardwareInterface *>(user); + // Start refcounting the heap object from here on. When the clients + // drop all references, it will be destroyed (as well as the enclosed + // MemoryHeapBase. + sp<CameraHeapMemory> mem(static_cast<CameraHeapMemory *>(data->handle)); + __this->mDataCbTimestamp(timestamp, msg_type, mem, __this->mCbUser); + } + + // This is a utility class that combines a MemoryHeapBase and a MemoryBase + // in one. Since we tend to use them in a one-to-one relationship, this is + // handy. + + class CameraHeapMemory : public MemoryBase { + public: + CameraHeapMemory(size_t size) : + MemoryBase(new MemoryHeapBase(size), 0, size) + { + handle.data = getHeap()->base(); + handle.size = size; + handle.handle = this; + } + + camera_memory_t handle; + }; + + static camera_memory_t* __get_memory(size_t size, + void *user __attribute__((unused))) + { + // We allocate the object here, but we do not assign it to a strong + // pointer yet. The HAL will pass it back to us via the data callback + // or the data-timestamp callback, and from there on we will wrap it + // within a strong pointer. + + CameraHeapMemory *mem = new CameraHeapMemory(size); + return &mem->handle; + } + + static ANativeWindow *__to_anw(void *user) + { + CameraHardwareInterface *__this = + reinterpret_cast<CameraHardwareInterface *>(user); + return __this->mPreviewWindow.get(); + } +#define anw(n) __to_anw(((struct camera_preview_window *)n)->user) + + static int __dequeue_buffer(struct preview_stream_ops* w, + buffer_handle_t** buffer) + { + int rc; + ANativeWindow *a = anw(w); + struct android_native_buffer_t* anb; + rc = a->dequeueBuffer(a, &anb); + if (!rc) { + rc = a->lockBuffer(a, anb); + if (!rc) + *buffer = &anb->handle; + else + a->cancelBuffer(a, anb); + } + return rc; + } + +#ifndef container_of +#define container_of(ptr, type, member) ({ \ + const typeof(((type *) 0)->member) *__mptr = (ptr); \ + (type *) ((char *) __mptr - (char *)(&((type *)0)->member)); }) +#endif + + static int __enqueue_buffer(struct preview_stream_ops* w, + buffer_handle_t* buffer) + { + ANativeWindow *a = anw(w); + return a->queueBuffer(a, + container_of(buffer, android_native_buffer_t, handle)); + } + + static int __cancel_buffer(struct preview_stream_ops* w, + buffer_handle_t* buffer) + { + ANativeWindow *a = anw(w); + return a->cancelBuffer(a, + container_of(buffer, android_native_buffer_t, handle)); + } + + static int __set_buffer_count(struct preview_stream_ops* w, int count) + { + ANativeWindow *a = anw(w); + return a->perform(a, NATIVE_WINDOW_SET_BUFFER_COUNT, count); + } + + static int __set_buffers_geometry(struct preview_stream_ops* w, + int width, int height, int format) + { + ANativeWindow *a = anw(w); + return a->perform(a, NATIVE_WINDOW_SET_BUFFERS_GEOMETRY, + width, height, format); + } + + static int __set_crop(struct preview_stream_ops *w, + int left, int top, int right, int bottom) + { + ANativeWindow *a = anw(w); + android_native_rect_t crop; + crop.left = left; + crop.top = top; + crop.right = right; + crop.bottom = bottom; + return a->perform(a, NATIVE_WINDOW_SET_CROP, &crop); + } + + static int __set_usage(struct preview_stream_ops* w, int usage) + { + ANativeWindow *a = anw(w); + return a->perform(a, NATIVE_WINDOW_SET_USAGE, usage); + } + + static int __set_swap_interval(struct preview_stream_ops *w, int interval) + { + ANativeWindow *a = anw(w); + return a->setSwapInterval(a, interval); + } + + static int __get_min_undequeued_buffer_count( + const struct preview_stream_ops *w, + int *count) + { + ANativeWindow *a = anw(w); + return a->query(a, NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, count); + } + + void initHalPreviewWindow() + { + mHalPreviewWindow.nw.cancel_buffer = __cancel_buffer; + mHalPreviewWindow.nw.dequeue_buffer = __dequeue_buffer; + mHalPreviewWindow.nw.enqueue_buffer = __enqueue_buffer; + mHalPreviewWindow.nw.set_buffer_count = __set_buffer_count; + mHalPreviewWindow.nw.set_buffers_geometry = __set_buffers_geometry; + mHalPreviewWindow.nw.set_crop = __set_crop; + mHalPreviewWindow.nw.set_usage = __set_usage; + mHalPreviewWindow.nw.set_swap_interval = __set_swap_interval; + + mHalPreviewWindow.nw.get_min_undequeued_buffer_count = + __get_min_undequeued_buffer_count; + } + + sp<ANativeWindow> mPreviewWindow; + + struct camera_preview_window { + struct preview_stream_ops nw; + void *user; + }; + + struct camera_preview_window mHalPreviewWindow; + + notify_callback mNotifyCb; + data_callback mDataCb; + data_callback_timestamp mDataCbTimestamp; + void *mCbUser; +}; + +}; // namespace android + +#endif diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 56c9246..1e8c30b 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -16,6 +16,7 @@ */ #define LOG_TAG "CameraService" +//#define LOG_NDEBUG 0 #include <stdio.h> #include <sys/types.h> @@ -37,6 +38,7 @@ #include <utils/String16.h> #include "CameraService.h" +#include "CameraHardwareInterface.h" namespace android { @@ -69,22 +71,32 @@ static int getCallingUid() { static CameraService *gCameraService; CameraService::CameraService() -:mSoundRef(0) +:mSoundRef(0), mModule(0) { LOGI("CameraService started (pid=%d)", getpid()); + gCameraService = this; +} - mNumberOfCameras = HAL_getNumberOfCameras(); - if (mNumberOfCameras > MAX_CAMERAS) { - LOGE("Number of cameras(%d) > MAX_CAMERAS(%d).", - mNumberOfCameras, MAX_CAMERAS); - mNumberOfCameras = MAX_CAMERAS; - } - - for (int i = 0; i < mNumberOfCameras; i++) { - setCameraFree(i); +void CameraService::onFirstRef() +{ + BnCameraService::onFirstRef(); + + if (hw_get_module(CAMERA_HARDWARE_MODULE_ID, + (const hw_module_t **)&mModule) < 0) { + LOGE("Could not load camera HAL module"); + mNumberOfCameras = 0; + } + else { + mNumberOfCameras = mModule->get_number_of_cameras(); + if (mNumberOfCameras > MAX_CAMERAS) { + LOGE("Number of cameras(%d) > MAX_CAMERAS(%d).", + mNumberOfCameras, MAX_CAMERAS); + mNumberOfCameras = MAX_CAMERAS; + } + for (int i = 0; i < mNumberOfCameras; i++) { + setCameraFree(i); + } } - - gCameraService = this; } CameraService::~CameraService() { @@ -103,12 +115,19 @@ int32_t CameraService::getNumberOfCameras() { status_t CameraService::getCameraInfo(int cameraId, struct CameraInfo* cameraInfo) { + if (!mModule) { + return NO_INIT; + } + if (cameraId < 0 || cameraId >= mNumberOfCameras) { return BAD_VALUE; } - HAL_getCameraInfo(cameraId, cameraInfo); - return OK; + struct camera_info info; + status_t rc = mModule->get_camera_info(cameraId, &info); + cameraInfo->facing = info.facing; + cameraInfo->orientation = info.orientation; + return rc; } sp<ICamera> CameraService::connect( @@ -116,6 +135,11 @@ sp<ICamera> CameraService::connect( int callingPid = getCallingPid(); LOG1("CameraService::connect E (pid %d, id %d)", callingPid, cameraId); + if (!mModule) { + LOGE("Camera HAL module not loaded"); + return NULL; + } + sp<Client> client; if (cameraId < 0 || cameraId >= mNumberOfCameras) { LOGE("CameraService::connect X (pid %d) rejected (invalid cameraId %d).", @@ -146,15 +170,19 @@ sp<ICamera> CameraService::connect( return NULL; } - sp<CameraHardwareInterface> hardware = HAL_openCameraHardware(cameraId); - if (hardware == NULL) { - LOGE("Fail to open camera hardware (id=%d)", cameraId); + struct camera_info info; + if (mModule->get_camera_info(cameraId, &info) != OK) { + LOGE("Invalid camera id %d", cameraId); return NULL; } - CameraInfo info; - HAL_getCameraInfo(cameraId, &info); - client = new Client(this, cameraClient, hardware, cameraId, info.facing, - callingPid); + + char camera_device_name[10]; + snprintf(camera_device_name, sizeof(camera_device_name), "%d", cameraId); + + client = new Client(this, cameraClient, + new CameraHardwareInterface(&mModule->common, + camera_device_name), + cameraId, info.facing, callingPid); mClient[cameraId] = client; LOG1("CameraService::connect X"); return client; diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index 9a9ab0e..5e2d571 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -19,9 +19,8 @@ #define ANDROID_SERVERS_CAMERA_CAMERASERVICE_H #include <binder/BinderService.h> - #include <camera/ICameraService.h> -#include <camera/CameraHardwareInterface.h> +#include <hardware/camera.h> /* This needs to be increased if we can have more cameras */ #define MAX_CAMERAS 2 @@ -30,6 +29,7 @@ namespace android { class MemoryHeapBase; class MediaPlayer; +class CameraHardwareInterface; class CameraService : public BinderService<CameraService>, @@ -53,6 +53,7 @@ public: virtual status_t dump(int fd, const Vector<String16>& args); virtual status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); + virtual void onFirstRef(); enum sound_kind { SOUND_SHUTTER = 0, @@ -199,6 +200,8 @@ private: // is found to be disabled. It returns true if mLock is grabbed. bool lockIfMessageWanted(int32_t msgType); }; + + camera_module_t *mModule; }; } // namespace android |