Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit caf742fd authored by Kenny Root's avatar Kenny Root Committed by Android (Google) Code Review
Browse files

Merge "Add more error checking for ndc" into froyo

parents 4005afd0 7e27f057
Loading
Loading
Loading
Loading
+18 −15
Original line number Diff line number Diff line
LOCAL_PATH:= $(call my-dir)

#
# Set USE_CAMERA_STUB for non-emulator and non-simulator builds, if you want
# the camera service to use the fake camera.  For emulator or simulator builds,
# we always use the fake camera.
# Set USE_CAMERA_STUB if you don't want to use the hardware camera.

ifeq ($(USE_CAMERA_STUB),)
USE_CAMERA_STUB:=false
# force these builds to use camera stub only
ifneq ($(filter sooner generic sim,$(TARGET_DEVICE)),)
  USE_CAMERA_STUB:=true
endif #libcamerastub
endif

ifeq ($(USE_CAMERA_STUB),true)
  INCLUDE_CAMERA_STUB:=true
  INCLUDE_CAMERA_HARDWARE:=false
else
  INCLUDE_CAMERA_STUB:=true  # set this to true temporarily for testing
  INCLUDE_CAMERA_HARDWARE:=true
endif

ifeq ($(INCLUDE_CAMERA_STUB),true)
#
# libcamerastub
#
@@ -32,7 +35,7 @@ endif
LOCAL_SHARED_LIBRARIES:= libui

include $(BUILD_STATIC_LIBRARY)
endif # USE_CAMERA_STUB
endif # INCLUDE_CAMERA_STUB

#
# libcameraservice
@@ -54,18 +57,18 @@ LOCAL_SHARED_LIBRARIES:= \

LOCAL_MODULE:= libcameraservice

LOCAL_CFLAGS += -DLOG_TAG=\"CameraService\"

ifeq ($(TARGET_SIMULATOR),true)
LOCAL_CFLAGS += -DSINGLE_PROCESS
endif

ifeq ($(USE_CAMERA_STUB), true)
ifeq ($(INCLUDE_CAMERA_STUB), true)
LOCAL_STATIC_LIBRARIES += libcamerastub
LOCAL_CFLAGS += -include CameraHardwareStub.h
else
LOCAL_CFLAGS += -DINCLUDE_CAMERA_STUB
endif

ifeq ($(INCLUDE_CAMERA_HARDWARE),true)
LOCAL_CFLAGS += -DINCLUDE_CAMERA_HARDWARE
LOCAL_SHARED_LIBRARIES += libcamera 
endif

include $(BUILD_SHARED_LIBRARY)
+18 −27
Original line number Diff line number Diff line
@@ -47,14 +47,14 @@ void CameraHardwareStub::initDefaultParameters()
{
    CameraParameters p;

    p.set("preview-size-values","320x240");
    p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, "320x240");
    p.setPreviewSize(320, 240);
    p.setPreviewFrameRate(15);
    p.setPreviewFormat("yuv422sp");
    p.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420SP);

    p.set("picture-size-values", "320x240");
    p.set(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES, "320x240");
    p.setPictureSize(320, 240);
    p.setPictureFormat("jpeg");
    p.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);

    if (setParameters(p) != NO_ERROR) {
        LOGE("Failed to set default parameters?!");
@@ -66,14 +66,14 @@ void CameraHardwareStub::initHeapLocked()
    // Create raw heap.
    int picture_width, picture_height;
    mParameters.getPictureSize(&picture_width, &picture_height);
    mRawHeap = new MemoryHeapBase(picture_width * 2 * picture_height);
    mRawHeap = new MemoryHeapBase(picture_width * picture_height * 3 / 2);

    int preview_width, preview_height;
    mParameters.getPreviewSize(&preview_width, &preview_height);
    LOGD("initHeapLocked: preview size=%dx%d", preview_width, preview_height);

    // Note that we enforce yuv422 in setParameters().
    int how_big = preview_width * preview_height * 2;
    // Note that we enforce yuv420sp in setParameters().
    int how_big = preview_width * preview_height * 3 / 2;

    // If we are being reinitialized to the same size as before, no
    // work needs to be done.
@@ -99,7 +99,6 @@ CameraHardwareStub::~CameraHardwareStub()
{
    delete mFakeCamera;
    mFakeCamera = 0; // paranoia
    singleton.clear();
}

sp<IMemoryHeap> CameraHardwareStub::getPreviewHeap() const
@@ -175,7 +174,7 @@ int CameraHardwareStub::previewThread()

        // Fill the current frame with the fake camera.
        uint8_t *frame = ((uint8_t *)base) + offset;
        fakeCamera->getNextFrameAsYuv422(frame);
        fakeCamera->getNextFrameAsYuv420(frame);

        //LOGV("previewThread: generated frame to buffer %d", mCurrentPreviewFrame);

@@ -288,9 +287,9 @@ int CameraHardwareStub::pictureThread()
        // In the meantime just make another fake camera picture.
        int w, h;
        mParameters.getPictureSize(&w, &h);
        sp<MemoryBase> mem = new MemoryBase(mRawHeap, 0, w * 2 * h);
        sp<MemoryBase> mem = new MemoryBase(mRawHeap, 0, w * h * 3 / 2);
        FakeCamera cam(w, h);
        cam.getNextFrameAsYuv422((uint8_t *)mRawHeap->base());
        cam.getNextFrameAsYuv420((uint8_t *)mRawHeap->base());
        mDataCb(CAMERA_MSG_RAW_IMAGE, mem, mCallbackCookie);
    }

@@ -307,7 +306,7 @@ status_t CameraHardwareStub::takePicture()
{
    stopPreview();
    if (createThread(beginPictureThread, this) == false)
        return -1;
        return UNKNOWN_ERROR;
    return NO_ERROR;
}

@@ -339,12 +338,14 @@ status_t CameraHardwareStub::setParameters(const CameraParameters& params)
    Mutex::Autolock lock(mLock);
    // XXX verify params

    if (strcmp(params.getPreviewFormat(), "yuv422sp") != 0) {
        LOGE("Only yuv422sp preview is supported");
    if (strcmp(params.getPreviewFormat(),
        CameraParameters::PIXEL_FORMAT_YUV420SP) != 0) {
        LOGE("Only yuv420sp preview is supported");
        return -1;
    }

    if (strcmp(params.getPictureFormat(), "jpeg") != 0) {
    if (strcmp(params.getPictureFormat(),
        CameraParameters::PIXEL_FORMAT_JPEG) != 0) {
        LOGE("Only jpeg still pictures are supported");
        return -1;
    }
@@ -379,22 +380,12 @@ void CameraHardwareStub::release()
{
}

wp<CameraHardwareInterface> CameraHardwareStub::singleton;

sp<CameraHardwareInterface> CameraHardwareStub::createInstance()
{
    if (singleton != 0) {
        sp<CameraHardwareInterface> hardware = singleton.promote();
        if (hardware != 0) {
            return hardware;
        }
    }
    sp<CameraHardwareInterface> hardware(new CameraHardwareStub());
    singleton = hardware;
    return hardware;
    return new CameraHardwareStub();
}

extern "C" sp<CameraHardwareInterface> openCameraHardware()
extern "C" sp<CameraHardwareInterface> openCameraHardwareStub()
{
    return CameraHardwareStub::createInstance();
}
+2 −2
Original line number Diff line number Diff line
@@ -67,8 +67,6 @@ private:
                        CameraHardwareStub();
    virtual             ~CameraHardwareStub();

    static wp<CameraHardwareInterface> singleton;

    static const int kBufferCount = 4;

    class PreviewThread : public Thread {
@@ -130,6 +128,8 @@ private:
    int                 mCurrentPreviewFrame;
};

extern "C" sp<CameraHardwareInterface> openCameraHardwareStub();

}; // namespace android

#endif
+824 −955

File changed.

Preview size limit exceeded, changes collapsed.

+109 −145
Original line number Diff line number Diff line
@@ -21,207 +21,171 @@

#include <camera/ICameraService.h>
#include <camera/CameraHardwareInterface.h>
#include <camera/Camera.h>

/* This needs to be increased if we can have more cameras */
#define MAX_CAMERAS 2

namespace android {

class MemoryHeapBase;
class MediaPlayer;

// ----------------------------------------------------------------------------

#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))

// When enabled, this feature allows you to send an event to the CameraService
// so that you can cause all references to the heap object gWeakHeap, defined
// below, to be printed. You will also need to set DEBUG_REFS=1 and
// DEBUG_REFS_ENABLED_BY_DEFAULT=0 in libutils/RefBase.cpp. You just have to
// set gWeakHeap to the appropriate heap you want to track.

#define DEBUG_HEAP_LEAKS 0

// ----------------------------------------------------------------------------

class CameraService: public BnCameraService
{
    class Client;

public:
    static void         instantiate();

    // ICameraService interface
    virtual sp<ICamera>     connect(const sp<ICameraClient>& cameraClient);
                        CameraService();
    virtual             ~CameraService();

    virtual int32_t     getNumberOfCameras();
    virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient, int cameraId);
    virtual void        removeClient(const sp<ICameraClient>& cameraClient);
    virtual sp<Client>  getClientById(int cameraId);

    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);

            void            removeClient(const sp<ICameraClient>& cameraClient);
    enum sound_kind {
        SOUND_SHUTTER = 0,
        SOUND_RECORDING = 1,
        NUM_SOUNDS
    };

    virtual status_t onTransact(
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
    void                loadSound();
    void                playSound(sound_kind kind);
    void                releaseSound();

private:
    Mutex               mServiceLock;
    wp<Client>          mClient[MAX_CAMERAS];  // protected by mServiceLock

// ----------------------------------------------------------------------------
    // atomics to record whether the hardware is allocated to some client.
    volatile int32_t    mBusy[MAX_CAMERAS];
    void                setCameraBusy(int cameraId);
    void                setCameraFree(int cameraId);

    class Client : public BnCamera {
    // sounds
    Mutex               mSoundLock;
    sp<MediaPlayer>     mSoundPlayer[NUM_SOUNDS];
    int                 mSoundRef;  // reference count (release all MediaPlayer when 0)

    class Client : public BnCamera
    {
    public:
        // ICamera interface (see ICamera for details)
        virtual void            disconnect();

        // connect new client with existing camera remote
        virtual status_t        connect(const sp<ICameraClient>& client);

        // prevent other processes from using this ICamera interface
        virtual status_t        lock();

        // allow other processes to use this ICamera interface
        virtual status_t        unlock();

        // pass the buffered ISurface to the camera service
        virtual status_t        setPreviewDisplay(const sp<ISurface>& surface);

        // set the preview callback flag to affect how the received frames from
        // preview are handled.
        virtual void            setPreviewCallbackFlag(int callback_flag);

        // start preview mode, must call setPreviewDisplay first
        virtual void            setPreviewCallbackFlag(int flag);
        virtual status_t        startPreview();

        // stop preview mode
        virtual void            stopPreview();

        // get preview state
        virtual bool            previewEnabled();

        // start recording mode
        virtual status_t        startRecording();

        // stop recording mode
        virtual void            stopRecording();

        // get recording state
        virtual bool            recordingEnabled();

        // release a recording frame
        virtual void            releaseRecordingFrame(const sp<IMemory>& mem);

        // auto focus
        virtual status_t        autoFocus();

        // cancel auto focus
        virtual status_t        cancelAutoFocus();

        // take a picture - returns an IMemory (ref-counted mmap)
        virtual status_t        takePicture();

        // set preview/capture parameters - key/value pairs
        virtual status_t        setParameters(const String8& params);

        // get preview/capture parameters - key/value pairs
        virtual String8         getParameters() const;

        // send command to camera driver
        virtual status_t        sendCommand(int32_t cmd, int32_t arg1, int32_t arg2);

        // our client...
        const sp<ICameraClient>&    getCameraClient() const { return mCameraClient; }

    private:
        friend class CameraService;
                                Client(const sp<CameraService>& cameraService,
                                       const sp<ICameraClient>& cameraClient,
                                        pid_t clientPid);
                                Client();
        virtual                 ~Client();
                                       int cameraId,
                                       int clientPid);
                                ~Client();

                    status_t    checkPid();
        // return our camera client
        const sp<ICameraClient>&    getCameraClient() { return mCameraClient; }

        static      void        notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2, void* user);
        static      void        dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, void* user);
        static      void        dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType,
                                                      const sp<IMemory>& dataPtr, void* user);
        // check whether the calling process matches mClientPid.
        status_t                checkPid() const;
        status_t                checkPidAndHardware() const;  // also check mHardware != 0

        static      sp<Client>  getClientFromCookie(void* user);

                    void        handlePreviewData(const sp<IMemory>&);
                    void        handleShutter(image_rect_type *image);
                    void        handlePostview(const sp<IMemory>&);
                    void        handleRawPicture(const sp<IMemory>&);
                    void        handleCompressedPicture(const sp<IMemory>&);

                    void        copyFrameAndPostCopiedFrame(const sp<ICameraClient>& client,
                                    const sp<IMemoryHeap>& heap, size_t offset, size_t size);
        // these are internal functions used to set up preview buffers
        status_t                registerPreviewBuffers();
        status_t                setOverlay();

        // camera operation mode
        enum camera_mode {
            CAMERA_PREVIEW_MODE   = 0,  // frame automatically released
            CAMERA_RECORDING_MODE = 1,  // frame has to be explicitly released by releaseRecordingFrame()
        };
        // these are internal functions used for preview/recording
        status_t                startCameraMode(camera_mode mode);
        status_t                startPreviewMode();
        status_t                startRecordingMode();
        status_t                setOverlay();
        status_t                registerPreviewBuffers();

        // Ensures atomicity among the public methods
        mutable     Mutex                       mLock;

        // mSurfaceLock synchronizes access to mSurface between
        // setPreviewSurface() and postPreviewFrame().  Note that among
        // the public methods, all accesses to mSurface are
        // syncrhonized by mLock.  However, postPreviewFrame() is called
        // by the CameraHardwareInterface callback, and needs to
        // access mSurface.  It cannot hold mLock, however, because
        // stopPreview() may be holding that lock while attempting
        // to stop preview, and stopPreview itself will block waiting
        // for a callback from CameraHardwareInterface.  If this
        // happens, it will cause a deadlock.
        mutable     Mutex                       mSurfaceLock;
        mutable     Condition                   mReady;
                    sp<CameraService>           mCameraService;
                    sp<ISurface>                mSurface;
                    int                         mPreviewCallbackFlag;
                    int                         mOrientation;

                    sp<MediaPlayer>             mMediaPlayerClick;
                    sp<MediaPlayer>             mMediaPlayerBeep;

                    // these are immutable once the object is created,
                    // they don't need to be protected by a lock
        // these are static callback functions
        static void             notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2, void* user);
        static void             dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, void* user);
        static void             dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr, void* user);
        // convert client from cookie
        static sp<Client>       getClientFromCookie(void* user);
        // handlers for messages
        void                    handleShutter(image_rect_type *size);
        void                    handlePreviewData(const sp<IMemory>& mem);
        void                    handlePostview(const sp<IMemory>& mem);
        void                    handleRawPicture(const sp<IMemory>& mem);
        void                    handleCompressedPicture(const sp<IMemory>& mem);
        void                    handleGenericNotify(int32_t msgType, int32_t ext1, int32_t ext2);
        void                    handleGenericData(int32_t msgType, const sp<IMemory>& dataPtr);
        void                    handleGenericDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);

        void                    copyFrameAndPostCopiedFrame(
                                    const sp<ICameraClient>& client,
                                    const sp<IMemoryHeap>& heap,
                                    size_t offset, size_t size);

        // these are initialized in the constructor.
        sp<CameraService>               mCameraService;  // immutable after constructor
        sp<ICameraClient>               mCameraClient;
                    sp<CameraHardwareInterface> mHardware;
        int                             mCameraId;       // immutable after constructor
        pid_t                           mClientPid;
                    bool                        mUseOverlay;

        sp<CameraHardwareInterface>     mHardware;       // cleared after disconnect()
        bool                            mUseOverlay;     // immutable after constructor
        sp<OverlayRef>                  mOverlayRef;
        int                             mOverlayW;
        int                             mOverlayH;
        int                             mPreviewCallbackFlag;
        int                             mOrientation;

        mutable     Mutex                       mPreviewLock;
                    sp<MemoryHeapBase>          mPreviewBuffer;
    };

// ----------------------------------------------------------------------------

                            CameraService();
    virtual                 ~CameraService();

    // We use a count for number of clients (shoule only be 0 or 1).
    volatile    int32_t                     mUsers;
    virtual     void                        incUsers();
    virtual     void                        decUsers();
        // Ensures atomicity among the public methods
        mutable Mutex                   mLock;
        sp<ISurface>                    mSurface;

    mutable     Mutex                       mServiceLock;
                wp<Client>                  mClient;
        // If the user want us to return a copy of the preview frame (instead
        // of the original one), we allocate mPreviewBuffer and reuse it if possible.
        sp<MemoryHeapBase>              mPreviewBuffer;

#if DEBUG_HEAP_LEAKS
                wp<IMemoryHeap>             gWeakHeap;
#endif
        // We need to avoid the deadlock when the incoming command thread and
        // the CameraHardwareInterface callback thread both want to grab mLock.
        // An extra flag is used to tell the callback thread that it should stop
        // trying to deliver the callback messages if the client is not
        // interested in it anymore. For example, if the client is calling
        // stopPreview(), the preview frame messages do not need to be delivered
        // anymore.

        // This function takes the same parameter as the enableMsgType() and
        // disableMsgType() functions in CameraHardwareInterface.
        void                    enableMsgType(int32_t msgType);
        void                    disableMsgType(int32_t msgType);
        volatile int32_t        mMsgEnabled;

        // This function keeps trying to grab mLock, or give up if the message
        // is found to be disabled. It returns true if mLock is grabbed.
        bool                    lockIfMessageWanted(int32_t msgType);
    };
};

// ----------------------------------------------------------------------------

}; // namespace android
} // namespace android

#endif
Loading