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 Original line Diff line number Diff line
LOCAL_PATH:= $(call my-dir)
LOCAL_PATH:= $(call my-dir)


#
# Set USE_CAMERA_STUB if you don't want to use the hardware camera.
# 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.


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


ifeq ($(USE_CAMERA_STUB),true)
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
# libcamerastub
#
#
@@ -32,7 +35,7 @@ endif
LOCAL_SHARED_LIBRARIES:= libui
LOCAL_SHARED_LIBRARIES:= libui


include $(BUILD_STATIC_LIBRARY)
include $(BUILD_STATIC_LIBRARY)
endif # USE_CAMERA_STUB
endif # INCLUDE_CAMERA_STUB


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


LOCAL_MODULE:= libcameraservice
LOCAL_MODULE:= libcameraservice


LOCAL_CFLAGS += -DLOG_TAG=\"CameraService\"

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


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

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


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


    p.set("preview-size-values","320x240");
    p.set(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES, "320x240");
    p.setPreviewSize(320, 240);
    p.setPreviewSize(320, 240);
    p.setPreviewFrameRate(15);
    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.setPictureSize(320, 240);
    p.setPictureFormat("jpeg");
    p.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);


    if (setParameters(p) != NO_ERROR) {
    if (setParameters(p) != NO_ERROR) {
        LOGE("Failed to set default parameters?!");
        LOGE("Failed to set default parameters?!");
@@ -66,14 +66,14 @@ void CameraHardwareStub::initHeapLocked()
    // Create raw heap.
    // Create raw heap.
    int picture_width, picture_height;
    int picture_width, picture_height;
    mParameters.getPictureSize(&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;
    int preview_width, preview_height;
    mParameters.getPreviewSize(&preview_width, &preview_height);
    mParameters.getPreviewSize(&preview_width, &preview_height);
    LOGD("initHeapLocked: preview size=%dx%d", preview_width, preview_height);
    LOGD("initHeapLocked: preview size=%dx%d", preview_width, preview_height);


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


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


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


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


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


@@ -288,9 +287,9 @@ int CameraHardwareStub::pictureThread()
        // In the meantime just make another fake camera picture.
        // In the meantime just make another fake camera picture.
        int w, h;
        int w, h;
        mParameters.getPictureSize(&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);
        FakeCamera cam(w, h);
        cam.getNextFrameAsYuv422((uint8_t *)mRawHeap->base());
        cam.getNextFrameAsYuv420((uint8_t *)mRawHeap->base());
        mDataCb(CAMERA_MSG_RAW_IMAGE, mem, mCallbackCookie);
        mDataCb(CAMERA_MSG_RAW_IMAGE, mem, mCallbackCookie);
    }
    }


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


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


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


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


wp<CameraHardwareInterface> CameraHardwareStub::singleton;

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


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


    static wp<CameraHardwareInterface> singleton;

    static const int kBufferCount = 4;
    static const int kBufferCount = 4;


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


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

}; // namespace android
}; // namespace android


#endif
#endif
+824 −955

File changed.

Preview size limit exceeded, changes collapsed.

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


#include <camera/ICameraService.h>
#include <camera/ICameraService.h>
#include <camera/CameraHardwareInterface.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 {
namespace android {


class MemoryHeapBase;
class MemoryHeapBase;
class MediaPlayer;
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 CameraService: public BnCameraService
{
{
    class Client;
    class Client;

public:
public:
    static void         instantiate();
    static void         instantiate();


    // ICameraService interface
                        CameraService();
    virtual sp<ICamera>     connect(const sp<ICameraClient>& cameraClient);
    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    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(
    void                loadSound();
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
    void                playSound(sound_kind kind);
    void                releaseSound();


private:
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:
    public:
        // ICamera interface (see ICamera for details)
        virtual void            disconnect();
        virtual void            disconnect();

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

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

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

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

        virtual void            setPreviewCallbackFlag(int flag);
        // 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 status_t        startPreview();
        virtual status_t        startPreview();

        // stop preview mode
        virtual void            stopPreview();
        virtual void            stopPreview();

        // get preview state
        virtual bool            previewEnabled();
        virtual bool            previewEnabled();

        // start recording mode
        virtual status_t        startRecording();
        virtual status_t        startRecording();

        // stop recording mode
        virtual void            stopRecording();
        virtual void            stopRecording();

        // get recording state
        virtual bool            recordingEnabled();
        virtual bool            recordingEnabled();

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

        // auto focus
        virtual status_t        autoFocus();
        virtual status_t        autoFocus();

        // cancel auto focus
        virtual status_t        cancelAutoFocus();
        virtual status_t        cancelAutoFocus();

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

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

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

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

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

    private:
    private:
        friend class CameraService;
        friend class CameraService;
                                Client(const sp<CameraService>& cameraService,
                                Client(const sp<CameraService>& cameraService,
                                       const sp<ICameraClient>& cameraClient,
                                       const sp<ICameraClient>& cameraClient,
                                        pid_t clientPid);
                                       int cameraId,
                                Client();
                                       int clientPid);
        virtual                 ~Client();
                                ~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);
        // check whether the calling process matches mClientPid.
        static      void        dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, void* user);
        status_t                checkPid() const;
        static      void        dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType,
        status_t                checkPidAndHardware() const;  // also check mHardware != 0
                                                      const sp<IMemory>& dataPtr, void* user);


        static      sp<Client>  getClientFromCookie(void* user);
        // these are internal functions used to set up preview buffers

        status_t                registerPreviewBuffers();
                    void        handlePreviewData(const sp<IMemory>&);
        status_t                setOverlay();
                    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);


        // camera operation mode
        // camera operation mode
        enum camera_mode {
        enum camera_mode {
            CAMERA_PREVIEW_MODE   = 0,  // frame automatically released
            CAMERA_PREVIEW_MODE   = 0,  // frame automatically released
            CAMERA_RECORDING_MODE = 1,  // frame has to be explicitly released by releaseRecordingFrame()
            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                startCameraMode(camera_mode mode);
        status_t                startPreviewMode();
        status_t                startPreviewMode();
        status_t                startRecordingMode();
        status_t                startRecordingMode();
        status_t                setOverlay();
        status_t                registerPreviewBuffers();

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


        // mSurfaceLock synchronizes access to mSurface between
        // these are static callback functions
        // setPreviewSurface() and postPreviewFrame().  Note that among
        static void             notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2, void* user);
        // the public methods, all accesses to mSurface are
        static void             dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, void* user);
        // syncrhonized by mLock.  However, postPreviewFrame() is called
        static void             dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr, void* user);
        // by the CameraHardwareInterface callback, and needs to
        // convert client from cookie
        // access mSurface.  It cannot hold mLock, however, because
        static sp<Client>       getClientFromCookie(void* user);
        // stopPreview() may be holding that lock while attempting
        // handlers for messages
        // to stop preview, and stopPreview itself will block waiting
        void                    handleShutter(image_rect_type *size);
        // for a callback from CameraHardwareInterface.  If this
        void                    handlePreviewData(const sp<IMemory>& mem);
        // happens, it will cause a deadlock.
        void                    handlePostview(const sp<IMemory>& mem);
        mutable     Mutex                       mSurfaceLock;
        void                    handleRawPicture(const sp<IMemory>& mem);
        mutable     Condition                   mReady;
        void                    handleCompressedPicture(const sp<IMemory>& mem);
                    sp<CameraService>           mCameraService;
        void                    handleGenericNotify(int32_t msgType, int32_t ext1, int32_t ext2);
                    sp<ISurface>                mSurface;
        void                    handleGenericData(int32_t msgType, const sp<IMemory>& dataPtr);
                    int                         mPreviewCallbackFlag;
        void                    handleGenericDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr);
                    int                         mOrientation;


        void                    copyFrameAndPostCopiedFrame(
                    sp<MediaPlayer>             mMediaPlayerClick;
                                    const sp<ICameraClient>& client,
                    sp<MediaPlayer>             mMediaPlayerBeep;
                                    const sp<IMemoryHeap>& heap,

                                    size_t offset, size_t size);
                    // these are immutable once the object is created,

                    // they don't need to be protected by a lock
        // these are initialized in the constructor.
        sp<CameraService>               mCameraService;  // immutable after constructor
        sp<ICameraClient>               mCameraClient;
        sp<ICameraClient>               mCameraClient;
                    sp<CameraHardwareInterface> mHardware;
        int                             mCameraId;       // immutable after constructor
        pid_t                           mClientPid;
        pid_t                           mClientPid;
                    bool                        mUseOverlay;
        sp<CameraHardwareInterface>     mHardware;       // cleared after disconnect()

        bool                            mUseOverlay;     // immutable after constructor
        sp<OverlayRef>                  mOverlayRef;
        sp<OverlayRef>                  mOverlayRef;
        int                             mOverlayW;
        int                             mOverlayW;
        int                             mOverlayH;
        int                             mOverlayH;
        int                             mPreviewCallbackFlag;
        int                             mOrientation;


        mutable     Mutex                       mPreviewLock;
        // Ensures atomicity among the public methods
                    sp<MemoryHeapBase>          mPreviewBuffer;
        mutable Mutex                   mLock;
    };
        sp<ISurface>                    mSurface;

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

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


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


#if DEBUG_HEAP_LEAKS
        // We need to avoid the deadlock when the incoming command thread and
                wp<IMemoryHeap>             gWeakHeap;
        // the CameraHardwareInterface callback thread both want to grab mLock.
#endif
        // 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
#endif
Loading