diff options
| -rw-r--r-- | core/jni/android_hardware_Camera.cpp | 14 | ||||
| -rw-r--r-- | include/camera/Camera.h | 108 | ||||
| -rw-r--r-- | include/camera/CameraHardwareInterface.h | 266 | ||||
| -rw-r--r-- | include/gui/SurfaceTextureClient.h | 4 | ||||
| -rw-r--r-- | include/surfaceflinger/Surface.h | 4 | ||||
| -rw-r--r-- | include/ui/FramebufferNativeWindow.h | 2 | ||||
| -rw-r--r-- | include/ui/egl/android_natives.h | 2 | ||||
| -rw-r--r-- | libs/gui/Surface.cpp | 6 | ||||
| -rw-r--r-- | libs/gui/SurfaceTextureClient.cpp | 7 | ||||
| -rw-r--r-- | libs/ui/FramebufferNativeWindow.cpp | 4 | ||||
| -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 | 88 | ||||
| -rw-r--r-- | services/camera/libcameraservice/CameraService.h | 7 | ||||
| -rw-r--r-- | services/camera/tests/CameraServiceTest/CameraServiceTest.cpp | 8 |
15 files changed, 717 insertions, 468 deletions
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp index 97580f54cde3..4687ee07f6fd 100644 --- a/core/jni/android_hardware_Camera.cpp +++ b/core/jni/android_hardware_Camera.cpp @@ -218,7 +218,7 @@ void JNICameraContext::copyAndPost(JNIEnv* env, const sp<IMemory>& dataPtr, int if (mCallbackBuffers.isEmpty()) { LOGV("Out of buffers, clearing callback!"); - mCamera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_NOOP); + mCamera->setPreviewCallbackFlags(CAMERA_FRAME_CALLBACK_FLAG_NOOP); mManualCameraCallbackSet = false; if (obj == NULL) { @@ -305,22 +305,22 @@ void JNICameraContext::setCallbackMode(JNIEnv *env, bool installed, bool manualM mManualCameraCallbackSet = false; // In order to limit the over usage of binder threads, all non-manual buffer - // callbacks use FRAME_CALLBACK_FLAG_BARCODE_SCANNER mode now. + // callbacks use CAMERA_FRAME_CALLBACK_FLAG_BARCODE_SCANNER mode now. // // Continuous callbacks will have the callback re-registered from handleMessage. // Manual buffer mode will operate as fast as possible, relying on the finite supply // of buffers for throttling. if (!installed) { - mCamera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_NOOP); + mCamera->setPreviewCallbackFlags(CAMERA_FRAME_CALLBACK_FLAG_NOOP); clearCallbackBuffers_l(env, &mCallbackBuffers); } else if (mManualBufferMode) { if (!mCallbackBuffers.isEmpty()) { - mCamera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_CAMERA); + mCamera->setPreviewCallbackFlags(CAMERA_FRAME_CALLBACK_FLAG_CAMERA); mManualCameraCallbackSet = true; } } else { - mCamera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_BARCODE_SCANNER); + mCamera->setPreviewCallbackFlags(CAMERA_FRAME_CALLBACK_FLAG_BARCODE_SCANNER); clearCallbackBuffers_l(env, &mCallbackBuffers); } } @@ -343,7 +343,7 @@ void JNICameraContext::addCallbackBuffer( // next frame. This may have come unset had we not had a // callbackbuffer ready for it last time. if (mManualBufferMode && !mManualCameraCallbackSet) { - mCamera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_CAMERA); + mCamera->setPreviewCallbackFlags(CAMERA_FRAME_CALLBACK_FLAG_CAMERA); mManualCameraCallbackSet = true; } break; @@ -456,7 +456,7 @@ static void android_hardware_Camera_release(JNIEnv *env, jobject thiz) // clear callbacks if (camera != NULL) { - camera->setPreviewCallbackFlags(FRAME_CALLBACK_FLAG_NOOP); + camera->setPreviewCallbackFlags(CAMERA_FRAME_CALLBACK_FLAG_NOOP); camera->disconnect(); } diff --git a/include/camera/Camera.h b/include/camera/Camera.h index 3c6dccc73e61..7106bfa6606f 100644 --- a/include/camera/Camera.h +++ b/include/camera/Camera.h @@ -20,122 +20,28 @@ #include <utils/Timers.h> #include <camera/ICameraClient.h> #include <gui/ISurfaceTexture.h> +#include <system/camera.h> namespace android { -/* - * A set of bit masks for specifying how the received preview frames are - * handled before the previewCallback() call. - * - * The least significant 3 bits of an "int" value are used for this purpose: - * - * ..... 0 0 0 - * ^ ^ ^ - * | | |---------> determine whether the callback is enabled or not - * | |-----------> determine whether the callback is one-shot or not - * |-------------> determine whether the frame is copied out or not - * - * WARNING: - * When a frame is sent directly without copying, it is the frame receiver's - * responsiblity to make sure that the frame data won't get corrupted by - * subsequent preview frames filled by the camera. This flag is recommended - * only when copying out data brings significant performance price and the - * handling/processing of the received frame data is always faster than - * the preview frame rate so that data corruption won't occur. - * - * For instance, - * 1. 0x00 disables the callback. In this case, copy out and one shot bits - * are ignored. - * 2. 0x01 enables a callback without copying out the received frames. A - * typical use case is the Camcorder application to avoid making costly - * frame copies. - * 3. 0x05 is enabling a callback with frame copied out repeatedly. A typical - * use case is the Camera application. - * 4. 0x07 is enabling a callback with frame copied out only once. A typical use - * case is the Barcode scanner application. - */ -#define FRAME_CALLBACK_FLAG_ENABLE_MASK 0x01 -#define FRAME_CALLBACK_FLAG_ONE_SHOT_MASK 0x02 -#define FRAME_CALLBACK_FLAG_COPY_OUT_MASK 0x04 - -// Typical use cases -#define FRAME_CALLBACK_FLAG_NOOP 0x00 -#define FRAME_CALLBACK_FLAG_CAMCORDER 0x01 -#define FRAME_CALLBACK_FLAG_CAMERA 0x05 -#define FRAME_CALLBACK_FLAG_BARCODE_SCANNER 0x07 - -// msgType in notifyCallback and dataCallback functions -enum { - CAMERA_MSG_ERROR = 0x0001, - CAMERA_MSG_SHUTTER = 0x0002, - CAMERA_MSG_FOCUS = 0x0004, - CAMERA_MSG_ZOOM = 0x0008, - CAMERA_MSG_PREVIEW_FRAME = 0x0010, - CAMERA_MSG_VIDEO_FRAME = 0x0020, - CAMERA_MSG_POSTVIEW_FRAME = 0x0040, - CAMERA_MSG_RAW_IMAGE = 0x0080, - CAMERA_MSG_COMPRESSED_IMAGE = 0x0100, - CAMERA_MSG_RAW_IMAGE_NOTIFY = 0x0200, - CAMERA_MSG_ALL_MSGS = 0xFFFF -}; - -// cmdType in sendCommand functions -enum { - CAMERA_CMD_START_SMOOTH_ZOOM = 1, - CAMERA_CMD_STOP_SMOOTH_ZOOM = 2, - // Set the clockwise rotation of preview display (setPreviewDisplay) in - // degrees. This affects the preview frames and the picture displayed after - // snapshot. This method is useful for portrait mode applications. Note that - // preview display of front-facing cameras is flipped horizontally before - // the rotation, that is, the image is reflected along the central vertical - // axis of the camera sensor. So the users can see themselves as looking - // into a mirror. - // - // This does not affect the order of byte array of CAMERA_MSG_PREVIEW_FRAME, - // CAMERA_MSG_VIDEO_FRAME, CAMERA_MSG_POSTVIEW_FRAME, CAMERA_MSG_RAW_IMAGE, - // or CAMERA_MSG_COMPRESSED_IMAGE. This is not allowed to be set during - // preview. - CAMERA_CMD_SET_DISPLAY_ORIENTATION = 3, - - // cmdType to disable/enable shutter sound. - // In sendCommand passing arg1 = 0 will disable, - // while passing arg1 = 1 will enable the shutter sound. - CAMERA_CMD_ENABLE_SHUTTER_SOUND = 4, - - // cmdType to play recording sound. - CAMERA_CMD_PLAY_RECORDING_SOUND = 5, -}; - -// camera fatal errors -enum { - CAMERA_ERROR_UNKNOWN = 1, - CAMERA_ERROR_SERVER_DIED = 100 -}; - -enum { - CAMERA_FACING_BACK = 0, /* The facing of the camera is opposite to that of the screen. */ - CAMERA_FACING_FRONT = 1 /* The facing of the camera is the same as that of the screen. */ -}; - struct CameraInfo { - /** - * The direction that the camera faces to. It should be - * CAMERA_FACING_BACK or CAMERA_FACING_FRONT. + * The direction that the camera faces to. It should be CAMERA_FACING_BACK + * or CAMERA_FACING_FRONT. */ int facing; /** * The orientation of the camera image. The value is the angle that the - * camera image needs to be rotated clockwise so it shows correctly on - * the display in its natural orientation. It should be 0, 90, 180, or 270. + * camera image needs to be rotated clockwise so it shows correctly on the + * display in its natural orientation. It should be 0, 90, 180, or 270. * * For example, suppose a device has a naturally tall screen. The * back-facing camera sensor is mounted in landscape. You are looking at * the screen. If the top side of the camera sensor is aligned with the * right edge of the screen in natural orientation, the value should be - * 90. If the top side of a front-facing camera sensor is aligned with - * the right of the screen, the value should be 270. + * 90. If the top side of a front-facing camera sensor is aligned with the + * right of the screen, the value should be 270. */ int orientation; }; diff --git a/include/camera/CameraHardwareInterface.h b/include/camera/CameraHardwareInterface.h deleted file mode 100644 index 3f34120dfff5..000000000000 --- a/include/camera/CameraHardwareInterface.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - * 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 <ui/egl/android_natives.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> - -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: - virtual ~CameraHardwareInterface() { } - - /** Set the ANativeWindow to which preview frames are sent */ - virtual status_t setPreviewWindow(const sp<ANativeWindow>& buf) = 0; - - /** Set the notification and data callbacks */ - virtual void setCallbacks(notify_callback notify_cb, - data_callback data_cb, - data_callback_timestamp data_cb_timestamp, - void* user) = 0; - - /** - * 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. - */ - virtual void enableMsgType(int32_t msgType) = 0; - - /** - * 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). - */ - virtual void disableMsgType(int32_t msgType) = 0; - - /** - * 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. - */ - virtual bool msgTypeEnabled(int32_t msgType) = 0; - - /** - * Start preview mode. - */ - virtual status_t startPreview() = 0; - - /** - * Stop a previously started preview. - */ - virtual void stopPreview() = 0; - - /** - * Returns true if preview is enabled. - */ - virtual bool previewEnabled() = 0; - - /** - * 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. - */ - virtual status_t storeMetaDataInBuffers(bool 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. - */ - virtual status_t startRecording() = 0; - - /** - * Stop a previously started recording. - */ - virtual void stopRecording() = 0; - - /** - * Returns true if recording is enabled. - */ - virtual bool recordingEnabled() = 0; - - /** - * 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. - */ - virtual void releaseRecordingFrame(const sp<IMemory>& mem) = 0; - - /** - * 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. - */ - virtual status_t autoFocus() = 0; - - /** - * 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. - */ - virtual status_t cancelAutoFocus() = 0; - - /** - * Take a picture. - */ - virtual status_t takePicture() = 0; - - /** - * Cancel a picture that was started with takePicture. Calling this - * method when no picture is being taken is a no-op. - */ - virtual status_t cancelPicture() = 0; - - /** - * Set the camera parameters. This returns BAD_VALUE if any parameter is - * invalid or not supported. */ - virtual status_t setParameters(const CameraParameters& params) = 0; - - /** Return the camera parameters. */ - virtual CameraParameters getParameters() const = 0; - - /** - * Send command to camera driver. - */ - virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) = 0; - - /** - * Release the hardware resources owned by this object. Note that this is - * *not* done in the destructor. - */ - virtual void release() = 0; - - /** - * Dump state of the camera hardware - */ - virtual status_t dump(int fd, const Vector<String16>& args) const = 0; -}; - -/** - * The functions need to be provided by the camera HAL. - * - * If getNumberOfCameras() returns N, the valid cameraId for getCameraInfo() - * and openCameraHardware() is 0 to N-1. - */ -extern "C" int HAL_getNumberOfCameras(); -extern "C" void HAL_getCameraInfo(int cameraId, struct CameraInfo* cameraInfo); -/* HAL should return NULL if it fails to open camera hardware. */ -extern "C" sp<CameraHardwareInterface> HAL_openCameraHardware(int cameraId); - -}; // namespace android - -#endif diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h index fe9b04917ed8..61ccbcb7697a 100644 --- a/include/gui/SurfaceTextureClient.h +++ b/include/gui/SurfaceTextureClient.h @@ -49,7 +49,7 @@ private: static int dequeueBuffer(ANativeWindow* window, android_native_buffer_t** buffer); static int lockBuffer(ANativeWindow* window, android_native_buffer_t* buffer); static int perform(ANativeWindow* window, int operation, ...); - static int query(ANativeWindow* window, int what, int* value); + static int query(const ANativeWindow* window, int what, int* value); static int queueBuffer(ANativeWindow* window, android_native_buffer_t* buffer); static int setSwapInterval(ANativeWindow* window, int interval); @@ -57,7 +57,7 @@ private: int dequeueBuffer(android_native_buffer_t** buffer); int lockBuffer(android_native_buffer_t* buffer); int perform(int operation, va_list args); - int query(int what, int* value); + int query(int what, int* value) const; int queueBuffer(android_native_buffer_t* buffer); int setSwapInterval(int interval); diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h index 3923e61ad8c5..31f24960911c 100644 --- a/include/surfaceflinger/Surface.h +++ b/include/surfaceflinger/Surface.h @@ -206,14 +206,14 @@ private: static int cancelBuffer(ANativeWindow* window, android_native_buffer_t* buffer); static int lockBuffer(ANativeWindow* window, android_native_buffer_t* buffer); static int queueBuffer(ANativeWindow* window, android_native_buffer_t* buffer); - static int query(ANativeWindow* window, int what, int* value); + static int query(const ANativeWindow* window, int what, int* value); static int perform(ANativeWindow* window, int operation, ...); int dequeueBuffer(android_native_buffer_t** buffer); int lockBuffer(android_native_buffer_t* buffer); int queueBuffer(android_native_buffer_t* buffer); int cancelBuffer(android_native_buffer_t* buffer); - int query(int what, int* value); + int query(int what, int* value) const; int perform(int operation, va_list args); void dispatch_setUsage(va_list args); diff --git a/include/ui/FramebufferNativeWindow.h b/include/ui/FramebufferNativeWindow.h index 16117adca92a..3e67f9689c7f 100644 --- a/include/ui/FramebufferNativeWindow.h +++ b/include/ui/FramebufferNativeWindow.h @@ -70,7 +70,7 @@ private: static int dequeueBuffer(ANativeWindow* window, android_native_buffer_t** buffer); static int lockBuffer(ANativeWindow* window, android_native_buffer_t* buffer); static int queueBuffer(ANativeWindow* window, android_native_buffer_t* buffer); - static int query(ANativeWindow* window, int what, int* value); + static int query(const ANativeWindow* window, int what, int* value); static int perform(ANativeWindow* window, int operation, ...); framebuffer_device_t* fbDev; diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h index 0a6e4fbd5e92..79339a4e7065 100644 --- a/include/ui/egl/android_natives.h +++ b/include/ui/egl/android_natives.h @@ -249,7 +249,7 @@ struct ANativeWindow * * Returns 0 on success or -errno on error. */ - int (*query)(struct ANativeWindow* window, + int (*query)(const struct ANativeWindow* window, int what, int* value); /* diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 44d9b4b4d329..812bd6ab2d57 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -536,9 +536,9 @@ int Surface::queueBuffer(ANativeWindow* window, return self->queueBuffer(buffer); } -int Surface::query(ANativeWindow* window, +int Surface::query(const ANativeWindow* window, int what, int* value) { - Surface* self = getSelf(window); + const Surface* self = getSelf(window); return self->query(what, value); } @@ -697,7 +697,7 @@ int Surface::queueBuffer(android_native_buffer_t* buffer) return err; } -int Surface::query(int what, int* value) +int Surface::query(int what, int* value) const { switch (what) { case NATIVE_WINDOW_WIDTH: diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp index f4b24162f0bf..76314496ea55 100644 --- a/libs/gui/SurfaceTextureClient.cpp +++ b/libs/gui/SurfaceTextureClient.cpp @@ -76,8 +76,9 @@ int SurfaceTextureClient::queueBuffer(ANativeWindow* window, return c->queueBuffer(buffer); } -int SurfaceTextureClient::query(ANativeWindow* window, int what, int* value) { - SurfaceTextureClient* c = getSelf(window); +int SurfaceTextureClient::query(const ANativeWindow* window, + int what, int* value) { + const SurfaceTextureClient* c = getSelf(window); return c->query(what, value); } @@ -160,7 +161,7 @@ int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) { return BAD_VALUE; } -int SurfaceTextureClient::query(int what, int* value) { +int SurfaceTextureClient::query(int what, int* value) const { LOGV("SurfaceTextureClient::query"); Mutex::Autolock lock(mMutex); switch (what) { diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp index dc223f96453a..0c820e5d7683 100644 --- a/libs/ui/FramebufferNativeWindow.cpp +++ b/libs/ui/FramebufferNativeWindow.cpp @@ -270,10 +270,10 @@ int FramebufferNativeWindow::queueBuffer(ANativeWindow* window, return res; } -int FramebufferNativeWindow::query(ANativeWindow* window, +int FramebufferNativeWindow::query(const ANativeWindow* window, int what, int* value) { - FramebufferNativeWindow* self = getSelf(window); + const FramebufferNativeWindow* self = getSelf(window); Mutex::Autolock _l(self->mutex); framebuffer_device_t* fb = self->fbDev; switch (what) { diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk index 14f1e8b1dfc3..e35435ef5400 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 000000000000..e30f7bf8e2d2 --- /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 f4859ec5b1c7..1e8c30b727db 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; @@ -320,7 +348,7 @@ CameraService::Client::Client(const sp<CameraService>& cameraService, CAMERA_MSG_FOCUS); // Callback is disabled by default - mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP; + mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP; mOrientation = getOrientation(0, mCameraFacing == CAMERA_FACING_FRONT); mPlayShutterSound = true; cameraService->setCameraBusy(cameraId); @@ -410,7 +438,7 @@ status_t CameraService::Client::connect(const sp<ICameraClient>& client) { return NO_ERROR; } - mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP; + mPreviewCallbackFlag = CAMERA_FRAME_CALLBACK_FLAG_NOOP; mClientPid = callingPid; mCameraClient = client; @@ -543,7 +571,7 @@ void CameraService::Client::setPreviewCallbackFlag(int callback_flag) { if (checkPidAndHardware() != NO_ERROR) return; mPreviewCallbackFlag = callback_flag; - if (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ENABLE_MASK) { + if (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) { enableMsgType(CAMERA_MSG_PREVIEW_FRAME); } else { disableMsgType(CAMERA_MSG_PREVIEW_FRAME); @@ -1009,7 +1037,7 @@ void CameraService::Client::handlePreviewData(const sp<IMemory>& mem) { int flags = mPreviewCallbackFlag; // is callback enabled? - if (!(flags & FRAME_CALLBACK_FLAG_ENABLE_MASK)) { + if (!(flags & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK)) { // If the enable bit is off, the copy-out and one-shot bits are ignored LOG2("frame callback is disabled"); mLock.unlock(); @@ -1020,17 +1048,17 @@ void CameraService::Client::handlePreviewData(const sp<IMemory>& mem) { sp<ICameraClient> c = mCameraClient; // clear callback flags if no client or one-shot mode - if (c == 0 || (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) { + if (c == 0 || (mPreviewCallbackFlag & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK)) { LOG2("Disable preview callback"); - mPreviewCallbackFlag &= ~(FRAME_CALLBACK_FLAG_ONE_SHOT_MASK | - FRAME_CALLBACK_FLAG_COPY_OUT_MASK | - FRAME_CALLBACK_FLAG_ENABLE_MASK); + mPreviewCallbackFlag &= ~(CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK | + CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK | + CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK); disableMsgType(CAMERA_MSG_PREVIEW_FRAME); } if (c != 0) { // Is the received frame copied out or not? - if (flags & FRAME_CALLBACK_FLAG_COPY_OUT_MASK) { + if (flags & CAMERA_FRAME_CALLBACK_FLAG_COPY_OUT_MASK) { LOG2("frame is copied"); copyFrameAndPostCopiedFrame(c, heap, offset, size); } else { diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index 9a9ab0ee5dfe..5e2d57151271 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 diff --git a/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp b/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp index 8a228fd7b6c4..f86ca475b678 100644 --- a/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp +++ b/services/camera/tests/CameraServiceTest/CameraServiceTest.cpp @@ -830,10 +830,10 @@ public: ASSERT(c->previewEnabled() == true); sleep(2); c->stopPreview(); - if ((v & FRAME_CALLBACK_FLAG_ENABLE_MASK) == 0) { + if ((v & CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK) == 0) { cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 0); } else { - if ((v & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) == 0) { + if ((v & CAMERA_FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) == 0) { cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::GE, 10); } else { cc->assertData(CAMERA_MSG_PREVIEW_FRAME, MCameraClient::EQ, 1); @@ -849,7 +849,7 @@ public: ASSERT(c->recordingEnabled() == false); sp<MSurface> surface = new MSurface(); ASSERT(c->setPreviewDisplay(surface) == NO_ERROR); - c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK); + c->setPreviewCallbackFlag(CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK); cc->setReleaser(c.get()); c->startRecording(); ASSERT(c->recordingEnabled() == true); @@ -870,7 +870,7 @@ public: CameraParameters param(c->getParameters()); param.setPreviewSize(w, h); - c->setPreviewCallbackFlag(FRAME_CALLBACK_FLAG_ENABLE_MASK); + c->setPreviewCallbackFlag(CAMERA_FRAME_CALLBACK_FLAG_ENABLE_MASK); c->setParameters(param.flatten()); c->startPreview(); |