diff options
-rw-r--r-- | camera/Android.mk | 1 | ||||
-rw-r--r-- | camera/Camera.cpp | 126 | ||||
-rw-r--r-- | camera/CameraBase.cpp | 237 | ||||
-rw-r--r-- | camera/ICameraService.cpp | 15 | ||||
-rw-r--r-- | camera/ProCamera.cpp | 153 | ||||
-rw-r--r-- | include/camera/Camera.h | 81 | ||||
-rw-r--r-- | include/camera/CameraBase.h | 117 | ||||
-rw-r--r-- | include/camera/ICameraService.h | 13 | ||||
-rw-r--r-- | include/camera/ProCamera.h | 65 | ||||
-rw-r--r-- | media/libstagefright/mpeg2ts/ESQueue.cpp | 2 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraService.cpp | 6 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraService.h | 7 |
12 files changed, 465 insertions, 358 deletions
diff --git a/camera/Android.mk b/camera/Android.mk index 3e7e5a5..3f30079 100644 --- a/camera/Android.mk +++ b/camera/Android.mk @@ -16,6 +16,7 @@ LOCAL_SRC_FILES:= \ IProCameraUser.cpp \ IProCameraCallbacks.cpp \ ProCamera.cpp \ + CameraBase.cpp \ LOCAL_SHARED_LIBRARIES := \ libcutils \ diff --git a/camera/Camera.cpp b/camera/Camera.cpp index d8dc2a5..f417c90 100644 --- a/camera/Camera.cpp +++ b/camera/Camera.cpp @@ -27,46 +27,16 @@ #include <camera/Camera.h> #include <camera/ICameraRecordingProxyListener.h> #include <camera/ICameraService.h> +#include <camera/ICamera.h> #include <gui/IGraphicBufferProducer.h> #include <gui/Surface.h> namespace android { -// client singleton for camera service binder interface -Mutex Camera::mLock; -sp<ICameraService> Camera::mCameraService; -sp<Camera::DeathNotifier> Camera::mDeathNotifier; - -// establish binder interface to camera service -const sp<ICameraService>& Camera::getCameraService() +Camera::Camera(int cameraId) + : CameraBase(cameraId) { - Mutex::Autolock _l(mLock); - if (mCameraService.get() == 0) { - sp<IServiceManager> sm = defaultServiceManager(); - sp<IBinder> binder; - do { - binder = sm->getService(String16("media.camera")); - if (binder != 0) - break; - ALOGW("CameraService not published, waiting..."); - usleep(500000); // 0.5 s - } while(true); - if (mDeathNotifier == NULL) { - mDeathNotifier = new DeathNotifier(); - } - binder->linkToDeath(mDeathNotifier); - mCameraService = interface_cast<ICameraService>(binder); - } - ALOGE_IF(mCameraService==0, "no CameraService!?"); - return mCameraService; -} - -// --------------------------------------------------------------------------- - -Camera::Camera() -{ - init(); } // construct a camera client from an existing camera remote @@ -78,7 +48,7 @@ sp<Camera> Camera::create(const sp<ICamera>& camera) return 0; } - sp<Camera> c = new Camera(); + sp<Camera> c = new Camera(-1); if (camera->connect(c) == NO_ERROR) { c->mStatus = NO_ERROR; c->mCamera = camera; @@ -88,11 +58,6 @@ sp<Camera> Camera::create(const sp<ICamera>& camera) return 0; } -void Camera::init() -{ - mStatus = UNKNOWN_ERROR; -} - Camera::~Camera() { // We don't need to call disconnect() here because if the CameraService @@ -103,47 +68,10 @@ Camera::~Camera() // deadlock if we call any method of ICamera here. } -int32_t Camera::getNumberOfCameras() -{ - const sp<ICameraService>& cs = getCameraService(); - if (cs == 0) return 0; - return cs->getNumberOfCameras(); -} - -status_t Camera::getCameraInfo(int cameraId, - struct CameraInfo* cameraInfo) { - const sp<ICameraService>& cs = getCameraService(); - if (cs == 0) return UNKNOWN_ERROR; - return cs->getCameraInfo(cameraId, cameraInfo); -} - sp<Camera> Camera::connect(int cameraId, const String16& clientPackageName, int clientUid) { - ALOGV("connect"); - sp<Camera> c = new Camera(); - sp<ICameraClient> cl = c; - const sp<ICameraService>& cs = getCameraService(); - if (cs != 0) { - c->mCamera = cs->connect(cl, cameraId, clientPackageName, clientUid); - } - if (c->mCamera != 0) { - c->mCamera->asBinder()->linkToDeath(c); - c->mStatus = NO_ERROR; - } else { - c.clear(); - } - return c; -} - -void Camera::disconnect() -{ - ALOGV("disconnect"); - if (mCamera != 0) { - mCamera->disconnect(); - mCamera->asBinder()->unlinkToDeath(this); - mCamera = 0; - } + return CameraBaseT::connect(cameraId, clientPackageName, clientUid); } status_t Camera::reconnect() @@ -154,11 +82,6 @@ status_t Camera::reconnect() return c->connect(this); } -sp<ICamera> Camera::remote() -{ - return mCamera; -} - status_t Camera::lock() { sp <ICamera> c = mCamera; @@ -353,28 +276,14 @@ void Camera::setPreviewCallbackFlags(int flag) // callback from camera service void Camera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) { - sp<CameraListener> listener; - { - Mutex::Autolock _l(mLock); - listener = mListener; - } - if (listener != NULL) { - listener->notify(msgType, ext1, ext2); - } + return CameraBaseT::notifyCallback(msgType, ext1, ext2); } // callback from camera service when frame or image is ready void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) { - sp<CameraListener> listener; - { - Mutex::Autolock _l(mLock); - listener = mListener; - } - if (listener != NULL) { - listener->postData(msgType, dataPtr, metadata); - } + return CameraBaseT::dataCallback(msgType, dataPtr, metadata); } // callback from camera service when timestamped frame is ready @@ -393,31 +302,12 @@ void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp< return; } - sp<CameraListener> listener; - { - Mutex::Autolock _l(mLock); - listener = mListener; - } - if (listener != NULL) { - listener->postDataTimestamp(timestamp, msgType, dataPtr); - } else { + if (!CameraBaseT::dataCallbackTimestamp(timestamp, msgType, dataPtr)) { ALOGW("No listener was set. Drop a recording frame."); releaseRecordingFrame(dataPtr); } } -void Camera::binderDied(const wp<IBinder>& who) { - ALOGW("ICamera died"); - notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0); -} - -void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) { - ALOGV("binderDied"); - Mutex::Autolock _l(Camera::mLock); - Camera::mCameraService.clear(); - ALOGW("Camera server died!"); -} - sp<ICameraRecordingProxy> Camera::getRecordingProxy() { ALOGV("getProxy"); return new RecordingProxy(this); diff --git a/camera/CameraBase.cpp b/camera/CameraBase.cpp new file mode 100644 index 0000000..9b0e6bf --- /dev/null +++ b/camera/CameraBase.cpp @@ -0,0 +1,237 @@ +/* +** +** Copyright (C) 2013, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "CameraBase" +#include <utils/Log.h> +#include <utils/threads.h> +#include <utils/Mutex.h> + +#include <binder/IPCThreadState.h> +#include <binder/IServiceManager.h> +#include <binder/IMemory.h> + +#include <camera/CameraBase.h> +#include <camera/ICameraService.h> + +// needed to instantiate +#include <camera/ProCamera.h> +#include <camera/Camera.h> + +#include <system/camera_metadata.h> + +namespace android { + +namespace { + sp<ICameraService> gCameraService; + const int kCameraServicePollDelay = 500000; // 0.5s + const char* kCameraServiceName = "media.camera"; + + Mutex gLock; + + class DeathNotifier : public IBinder::DeathRecipient + { + public: + DeathNotifier() { + } + + virtual void binderDied(const wp<IBinder>& who) { + ALOGV("binderDied"); + Mutex::Autolock _l(gLock); + gCameraService.clear(); + ALOGW("Camera service died!"); + } + }; + + sp<DeathNotifier> gDeathNotifier; +}; // namespace anonymous + +/////////////////////////////////////////////////////////// +// CameraBase definition +/////////////////////////////////////////////////////////// + +// establish binder interface to camera service +template <typename TCam, typename TCamTraits> +const sp<ICameraService>& CameraBase<TCam, TCamTraits>::getCameraService() +{ + Mutex::Autolock _l(gLock); + if (gCameraService.get() == 0) { + sp<IServiceManager> sm = defaultServiceManager(); + sp<IBinder> binder; + do { + binder = sm->getService(String16(kCameraServiceName)); + if (binder != 0) { + break; + } + ALOGW("CameraService not published, waiting..."); + usleep(kCameraServicePollDelay); + } while(true); + if (gDeathNotifier == NULL) { + gDeathNotifier = new DeathNotifier(); + } + binder->linkToDeath(gDeathNotifier); + gCameraService = interface_cast<ICameraService>(binder); + } + ALOGE_IF(gCameraService == 0, "no CameraService!?"); + return gCameraService; +} + +template <typename TCam, typename TCamTraits> +sp<TCam> CameraBase<TCam, TCamTraits>::connect(int cameraId, + const String16& clientPackageName, + int clientUid) +{ + ALOGV("%s: connect", __FUNCTION__); + sp<TCam> c = new TCam(cameraId); + sp<TCamCallbacks> cl = c; + const sp<ICameraService>& cs = getCameraService(); + if (cs != 0) { + c->mCamera = cs->connect(cl, cameraId, clientPackageName, clientUid); + } + if (c->mCamera != 0) { + c->mCamera->asBinder()->linkToDeath(c); + c->mStatus = NO_ERROR; + } else { + c.clear(); + } + return c; +} + +template <typename TCam, typename TCamTraits> +void CameraBase<TCam, TCamTraits>::disconnect() +{ + ALOGV("%s: disconnect", __FUNCTION__); + if (mCamera != 0) { + mCamera->disconnect(); + mCamera->asBinder()->unlinkToDeath(this); + mCamera = 0; + } + ALOGV("%s: disconnect (done)", __FUNCTION__); +} + +template <typename TCam, typename TCamTraits> +CameraBase<TCam, TCamTraits>::CameraBase(int cameraId) : + mStatus(UNKNOWN_ERROR), + mCameraId(cameraId) +{ +} + +template <typename TCam, typename TCamTraits> +CameraBase<TCam, TCamTraits>::~CameraBase() +{ +} + +template <typename TCam, typename TCamTraits> +sp<typename TCamTraits::TCamUser> CameraBase<TCam, TCamTraits>::remote() +{ + return mCamera; +} + +template <typename TCam, typename TCamTraits> +status_t CameraBase<TCam, TCamTraits>::getStatus() +{ + return mStatus; +} + +template <typename TCam, typename TCamTraits> +void CameraBase<TCam, TCamTraits>::binderDied(const wp<IBinder>& who) { + ALOGW("mediaserver's remote binder Camera object died"); + notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, /*ext2*/0); +} + +template <typename TCam, typename TCamTraits> +void CameraBase<TCam, TCamTraits>::setListener(const sp<TCamListener>& listener) +{ + Mutex::Autolock _l(mLock); + mListener = listener; +} + +// callback from camera service +template <typename TCam, typename TCamTraits> +void CameraBase<TCam, TCamTraits>::notifyCallback(int32_t msgType, + int32_t ext1, + int32_t ext2) +{ + sp<TCamListener> listener; + { + Mutex::Autolock _l(mLock); + listener = mListener; + } + if (listener != NULL) { + listener->notify(msgType, ext1, ext2); + } +} + +// callback from camera service when frame or image is ready +template <typename TCam, typename TCamTraits> +void CameraBase<TCam, TCamTraits>::dataCallback(int32_t msgType, + const sp<IMemory>& dataPtr, + camera_frame_metadata *metadata) +{ + sp<TCamListener> listener; + { + Mutex::Autolock _l(mLock); + listener = mListener; + } + if (listener != NULL) { + listener->postData(msgType, dataPtr, metadata); + } +} + +// callback from camera service when timestamped frame is ready +template <typename TCam, typename TCamTraits> +bool CameraBase<TCam, TCamTraits>::dataCallbackTimestamp(nsecs_t timestamp, + int32_t msgType, + const sp<IMemory>& dataPtr) +{ + sp<TCamListener> listener; + { + Mutex::Autolock _l(mLock); + listener = mListener; + } + if (listener != NULL) { + listener->postDataTimestamp(timestamp, msgType, dataPtr); + return true; + } + + return false; +} + +template <typename TCam, typename TCamTraits> +int CameraBase<TCam, TCamTraits>::getNumberOfCameras() { + const sp<ICameraService> cs = getCameraService(); + + if (!cs.get()) { + // as required by the public Java APIs + return 0; + } + return cs->getNumberOfCameras(); +} + +// this can be in BaseCamera but it should be an instance method +template <typename TCam, typename TCamTraits> +status_t CameraBase<TCam, TCamTraits>::getCameraInfo(int cameraId, + struct CameraInfo* cameraInfo) { + const sp<ICameraService>& cs = getCameraService(); + if (cs == 0) return UNKNOWN_ERROR; + return cs->getCameraInfo(cameraId, cameraInfo); +} + +template class CameraBase<ProCamera>; +template class CameraBase<Camera>; + +} // namespace android diff --git a/camera/ICameraService.cpp b/camera/ICameraService.cpp index fdf20ff..b54d63f 100644 --- a/camera/ICameraService.cpp +++ b/camera/ICameraService.cpp @@ -23,6 +23,10 @@ #include <binder/IServiceManager.h> #include <camera/ICameraService.h> +#include <camera/IProCameraUser.h> +#include <camera/IProCameraCallbacks.h> +#include <camera/ICamera.h> +#include <camera/ICameraClient.h> namespace android { @@ -70,12 +74,15 @@ public: } // connect to camera service (pro client) - virtual sp<IProCameraUser> connect(const sp<IProCameraCallbacks>& cameraCb, int cameraId) + virtual sp<IProCameraUser> connect(const sp<IProCameraCallbacks>& cameraCb, int cameraId, + const String16 &clientPackageName, int clientUid) { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); data.writeStrongBinder(cameraCb->asBinder()); data.writeInt32(cameraId); + data.writeString16(clientPackageName); + data.writeInt32(clientUid); remote()->transact(BnCameraService::CONNECT_PRO, data, &reply); return interface_cast<IProCameraUser>(reply.readStrongBinder()); } @@ -119,7 +126,11 @@ status_t BnCameraService::onTransact( case CONNECT_PRO: { CHECK_INTERFACE(ICameraService, data, reply); sp<IProCameraCallbacks> cameraClient = interface_cast<IProCameraCallbacks>(data.readStrongBinder()); - sp<IProCameraUser> camera = connect(cameraClient, data.readInt32()); + int32_t cameraId = data.readInt32(); + const String16 clientName = data.readString16(); + int32_t clientUid = data.readInt32(); + sp<IProCameraUser> camera = connect(cameraClient, cameraId, + clientName, clientUid); reply->writeStrongBinder(camera->asBinder()); return NO_ERROR; } break; diff --git a/camera/ProCamera.cpp b/camera/ProCamera.cpp index 7c66d62..13ba07c 100644 --- a/camera/ProCamera.cpp +++ b/camera/ProCamera.cpp @@ -31,71 +31,19 @@ #include <camera/IProCameraCallbacks.h> #include <gui/IGraphicBufferProducer.h> -#include <gui/Surface.h> #include <system/camera_metadata.h> namespace android { -// client singleton for camera service binder interface -Mutex ProCamera::mLock; -sp<ICameraService> ProCamera::mCameraService; -sp<ProCamera::DeathNotifier> ProCamera::mDeathNotifier; - -// establish binder interface to camera service -const sp<ICameraService>& ProCamera::getCameraService() -{ - Mutex::Autolock _l(mLock); - if (mCameraService.get() == 0) { - sp<IServiceManager> sm = defaultServiceManager(); - sp<IBinder> binder; - do { - binder = sm->getService(String16("media.camera")); - if (binder != 0) - break; - ALOGW("CameraService not published, waiting..."); - usleep(500000); // 0.5 s - } while(true); - if (mDeathNotifier == NULL) { - mDeathNotifier = new DeathNotifier(); - } - binder->linkToDeath(mDeathNotifier); - mCameraService = interface_cast<ICameraService>(binder); - } - ALOGE_IF(mCameraService==0, "no CameraService!?"); - return mCameraService; -} - sp<ProCamera> ProCamera::connect(int cameraId) { - ALOGV("connect"); - sp<ProCamera> c = new ProCamera(); - sp<IProCameraCallbacks> cl = c; - const sp<ICameraService>& cs = getCameraService(); - if (cs != 0) { - c->mCamera = cs->connect(cl, cameraId); - } - if (c->mCamera != 0) { - c->mCamera->asBinder()->linkToDeath(c); - c->mStatus = NO_ERROR; - } else { - c.clear(); - } - return c; -} - -void ProCamera::disconnect() -{ - ALOGV("%s: disconnect", __FUNCTION__); - if (mCamera != 0) { - mCamera->disconnect(); - mCamera->asBinder()->unlinkToDeath(this); - mCamera = 0; - } - ALOGV("%s: disconnect (done)", __FUNCTION__); + return CameraBaseT::connect(cameraId, String16(), + ICameraService::USE_CALLING_UID); } -ProCamera::ProCamera() +ProCamera::ProCamera(int cameraId) + : CameraBase(cameraId) { } @@ -104,74 +52,28 @@ ProCamera::~ProCamera() } -sp<IProCameraUser> ProCamera::remote() -{ - return mCamera; -} - -void ProCamera::binderDied(const wp<IBinder>& who) { - ALOGW("IProCameraUser died"); - notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, 0); -} - -void ProCamera::DeathNotifier::binderDied(const wp<IBinder>& who) { - ALOGV("binderDied"); - Mutex::Autolock _l(ProCamera::mLock); - ProCamera::mCameraService.clear(); - ALOGW("Camera service died!"); -} - -void ProCamera::setListener(const sp<ProCameraListener>& listener) -{ - Mutex::Autolock _l(mLock); - mListener = listener; -} - +/* IProCameraUser's implementation */ // callback from camera service void ProCamera::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2) { - sp<ProCameraListener> listener; - { - Mutex::Autolock _l(mLock); - listener = mListener; - } - if (listener != NULL) { - listener->notify(msgType, ext1, ext2); - } + return CameraBaseT::notifyCallback(msgType, ext1, ext2); } // callback from camera service when frame or image is ready void ProCamera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata) { - sp<ProCameraListener> listener; - { - Mutex::Autolock _l(mLock); - listener = mListener; - } - if (listener != NULL) { - listener->postData(msgType, dataPtr, metadata); - } + return CameraBaseT::dataCallback(msgType, dataPtr, metadata); } // callback from camera service when timestamped frame is ready void ProCamera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, - const sp<IMemory>& dataPtr) + const sp<IMemory>& dataPtr) { - sp<ProCameraListener> listener; - { - Mutex::Autolock _l(mLock); - listener = mListener; - } - if (listener != NULL) { - listener->postDataTimestamp(timestamp, msgType, dataPtr); - } else { - ALOGW("No listener was set. Drop a recording frame."); - } + CameraBaseT::dataCallbackTimestamp(timestamp, msgType, dataPtr); } -/* IProCameraUser's implementation */ void ProCamera::onLockStatusChanged( IProCameraCallbacks::LockStatus newLockStatus) @@ -291,9 +193,9 @@ status_t ProCamera::deleteStream(int streamId) } status_t ProCamera::createStream(int width, int height, int format, - const sp<Surface>& surface, - /*out*/ - int* streamId) + const sp<Surface>& surface, + /*out*/ + int* streamId) { *streamId = -1; @@ -304,14 +206,15 @@ status_t ProCamera::createStream(int width, int height, int format, return BAD_VALUE; } - return createStream(width, height, format, surface->getIGraphicBufferProducer(), + return createStream(width, height, format, + surface->getIGraphicBufferProducer(), streamId); } status_t ProCamera::createStream(int width, int height, int format, - const sp<IGraphicBufferProducer>& bufferProducer, - /*out*/ - int* streamId) { + const sp<IGraphicBufferProducer>& bufferProducer, + /*out*/ + int* streamId) { *streamId = -1; ALOGV("%s: createStreamT %dx%d (fmt=0x%x)", __FUNCTION__, width, height, @@ -335,10 +238,10 @@ status_t ProCamera::createStream(int width, int height, int format, } status_t ProCamera::createStreamCpu(int width, int height, int format, - int heapCount, - /*out*/ - sp<CpuConsumer>* cpuConsumer, - int* streamId) + int heapCount, + /*out*/ + sp<CpuConsumer>* cpuConsumer, + int* streamId) { ALOGV("%s: createStreamW %dx%d (fmt=0x%x)", __FUNCTION__, width, height, format); @@ -354,8 +257,9 @@ status_t ProCamera::createStreamCpu(int width, int height, int format, sp<Surface> stc = new Surface( cc->getProducerInterface()); - status_t s = createStream(width, height, format, stc->getIGraphicBufferProducer(), - streamId); + status_t s = createStream(width, height, format, + stc->getIGraphicBufferProducer(), + streamId); if (s != OK) { ALOGE("%s: Failure to create stream %dx%d (fmt=0x%x)", __FUNCTION__, @@ -379,15 +283,6 @@ status_t ProCamera::createStreamCpu(int width, int height, int format, return s; } -int ProCamera::getNumberOfCameras() { - const sp<ICameraService> cs = getCameraService(); - - if (!cs.get()) { - return DEAD_OBJECT; - } - return cs->getNumberOfCameras(); -} - camera_metadata* ProCamera::getCameraInfo(int cameraId) { ALOGV("%s: cameraId = %d", __FUNCTION__, cameraId); diff --git a/include/camera/Camera.h b/include/camera/Camera.h index be2b7f4..71c66ce 100644 --- a/include/camera/Camera.h +++ b/include/camera/Camera.h @@ -23,35 +23,13 @@ #include <camera/ICameraClient.h> #include <camera/ICameraRecordingProxy.h> #include <camera/ICameraRecordingProxyListener.h> +#include <camera/ICameraService.h> +#include <camera/ICamera.h> +#include <camera/CameraBase.h> namespace android { -struct CameraInfo { - /** - * 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. - * - * 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. - */ - int orientation; -}; - -class ICameraService; -class ICamera; class Surface; -class Mutex; class String8; class String16; @@ -65,32 +43,37 @@ public: virtual void postDataTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr) = 0; }; -class Camera : public BnCameraClient, public IBinder::DeathRecipient +class Camera; + +template <> +struct CameraTraits<Camera> +{ + typedef CameraListener TCamListener; + typedef ICamera TCamUser; + typedef ICameraClient TCamCallbacks; +}; + +class Camera : + public CameraBase<Camera>, + public BnCameraClient { public: enum { - USE_CALLING_UID = -1 + USE_CALLING_UID = ICameraService::USE_CALLING_UID }; // construct a camera client from an existing remote static sp<Camera> create(const sp<ICamera>& camera); - static int32_t getNumberOfCameras(); - static status_t getCameraInfo(int cameraId, - struct CameraInfo* cameraInfo); static sp<Camera> connect(int cameraId, const String16& clientPackageName, int clientUid); virtual ~Camera(); - void init(); status_t reconnect(); - void disconnect(); status_t lock(); status_t unlock(); - status_t getStatus() { return mStatus; } - // pass the buffered Surface to the camera service status_t setPreviewDisplay(const sp<Surface>& surface); @@ -151,8 +134,6 @@ public: camera_frame_metadata_t *metadata); virtual void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr); - sp<ICamera> remote(); - class RecordingProxy : public BnCameraRecordingProxy { public: @@ -168,35 +149,13 @@ public: }; protected: - Camera(); + Camera(int cameraId); Camera(const Camera&); Camera& operator=(const Camera); - virtual void binderDied(const wp<IBinder>& who); - - class DeathNotifier: public IBinder::DeathRecipient - { - public: - DeathNotifier() { - } - - virtual void binderDied(const wp<IBinder>& who); - }; - - static sp<DeathNotifier> mDeathNotifier; - - // helper function to obtain camera service handle - static const sp<ICameraService>& getCameraService(); - - sp<ICamera> mCamera; - status_t mStatus; - - sp<CameraListener> mListener; - sp<ICameraRecordingProxyListener> mRecordingProxyListener; - friend class DeathNotifier; + sp<ICameraRecordingProxyListener> mRecordingProxyListener; - static Mutex mLock; - static sp<ICameraService> mCameraService; + friend class CameraBase; }; }; // namespace android diff --git a/include/camera/CameraBase.h b/include/camera/CameraBase.h new file mode 100644 index 0000000..fed28ea --- /dev/null +++ b/include/camera/CameraBase.h @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2013 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_BASE_H +#define ANDROID_HARDWARE_CAMERA_BASE_H + +#include <utils/Mutex.h> +#include <camera/ICameraService.h> + +struct camera_frame_metadata; + +namespace android { + +struct CameraInfo { + /** + * 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. + * + * 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. + */ + int orientation; +}; + +template <typename TCam> +struct CameraTraits { +}; + +template <typename TCam, typename TCamTraits = CameraTraits<TCam> > +class CameraBase : public IBinder::DeathRecipient +{ +public: + typedef typename TCamTraits::TCamListener TCamListener; + typedef typename TCamTraits::TCamUser TCamUser; + typedef typename TCamTraits::TCamCallbacks TCamCallbacks; + + static sp<TCam> connect(int cameraId, + const String16& clientPackageName, + int clientUid); + virtual void disconnect(); + + void setListener(const sp<TCamListener>& listener); + + static int getNumberOfCameras(); + + static status_t getCameraInfo(int cameraId, + /*out*/ + struct CameraInfo* cameraInfo); + + sp<TCamUser> remote(); + + // Status is set to 'UNKNOWN_ERROR' after successful (re)connection + status_t getStatus(); + +protected: + CameraBase(int cameraId); + virtual ~CameraBase(); + + //////////////////////////////////////////////////////// + // TCamCallbacks implementation + //////////////////////////////////////////////////////// + virtual void notifyCallback(int32_t msgType, int32_t ext, + int32_t ext2); + virtual void dataCallback(int32_t msgType, + const sp<IMemory>& dataPtr, + camera_frame_metadata *metadata); + bool dataCallbackTimestamp(nsecs_t timestamp, + int32_t msgType, + const sp<IMemory>& dataPtr); + + //////////////////////////////////////////////////////// + // Common instance variables + //////////////////////////////////////////////////////// + Mutex mLock; + + virtual void binderDied(const wp<IBinder>& who); + + // helper function to obtain camera service handle + static const sp<ICameraService>& getCameraService(); + + sp<TCamUser> mCamera; + status_t mStatus; + + sp<TCamListener> mListener; + + const int mCameraId; + + typedef CameraBase<TCam> CameraBaseT; +}; + +}; // namespace android + +#endif diff --git a/include/camera/ICameraService.h b/include/camera/ICameraService.h index aa64243..ef2b685 100644 --- a/include/camera/ICameraService.h +++ b/include/camera/ICameraService.h @@ -21,12 +21,13 @@ #include <binder/IInterface.h> #include <binder/Parcel.h> -#include <camera/ICameraClient.h> -#include <camera/ICamera.h> -#include <camera/IProCameraUser.h> - namespace android { +class ICamera; +class ICameraClient; +class IProCameraUser; +class IProCameraCallbacks; + class ICameraService : public IInterface { public: @@ -58,7 +59,9 @@ public: int clientUid) = 0; virtual sp<IProCameraUser> connect(const sp<IProCameraCallbacks>& cameraCb, - int cameraId) = 0; + int cameraId, + const String16& clientPackageName, + int clientUid) = 0; }; // ---------------------------------------------------------------------------- diff --git a/include/camera/ProCamera.h b/include/camera/ProCamera.h index cd2772c..b228145 100644 --- a/include/camera/ProCamera.h +++ b/include/camera/ProCamera.h @@ -27,9 +27,13 @@ #include <camera/CameraMetadata.h> #include <gui/CpuConsumer.h> +#include <gui/Surface.h> + #include <utils/Condition.h> #include <utils/Mutex.h> +#include <camera/CameraBase.h> + struct camera_metadata; namespace android { @@ -53,6 +57,8 @@ public: // OnBufferReceived and OnRequestReceived can come in with any order, // use android.sensor.timestamp and LockedBuffer.timestamp to correlate them + // TODO: remove onBufferReceived + // A new frame buffer has been received for this stream. // -- This callback only fires for createStreamCpu streams // -- Use buf.timestamp to correlate with metadata's @@ -67,22 +73,36 @@ public: */ virtual void onResultReceived(int32_t frameId, camera_metadata* result) = 0; + // TODO: make onFrameAvailable pure virtual // A new frame buffer has been received for this stream. // -- This callback only fires for createStreamCpu streams // -- Use buf.timestamp to correlate with metadata's android.sensor.timestamp // -- The buffer should be accessed with CpuConsumer::lockNextBuffer // and CpuConsumer::unlockBuffer - virtual void onFrameAvailable(int streamId, - const sp<CpuConsumer>& cpuConsumer) { + virtual void onFrameAvailable(int /*streamId*/, + const sp<CpuConsumer>& /*cpuConsumer*/) { } + // TODO: Remove useOnFrameAvailable virtual bool useOnFrameAvailable() { return false; } }; -class ProCamera : public BnProCameraCallbacks, public IBinder::DeathRecipient +class ProCamera; + +template <> +struct CameraTraits<ProCamera> +{ + typedef ProCameraListener TCamListener; + typedef IProCameraUser TCamUser; + typedef IProCameraCallbacks TCamCallbacks; +}; + +class ProCamera : + public CameraBase<ProCamera>, + public BnProCameraCallbacks { public: /** @@ -91,11 +111,8 @@ public: * to be acquired with exclusive[Try]Lock. */ static sp<ProCamera> connect(int cameraId); - virtual void disconnect(); virtual ~ProCamera(); - void setListener(const sp<ProCameraListener>& listener); - /** * Exclusive Locks: * - We may request exclusive access to a camera if no other @@ -187,9 +204,6 @@ public: /*out*/ camera_metadata** request) const; - // Get number of cameras - static int getNumberOfCameras(); - // Get static camera metadata camera_metadata* getCameraInfo(int cameraId); @@ -222,8 +236,6 @@ public: // BAD_VALUE - invalid streamId or count passed int dropFrameBuffer(int streamId, int count); - sp<IProCameraUser> remote(); - protected: //////////////////////////////////////////////////////// // IProCameraCallbacks implementation @@ -241,35 +253,8 @@ protected: virtual void onResultReceived(int32_t frameId, camera_metadata* result); - - class DeathNotifier: public IBinder::DeathRecipient - { - public: - DeathNotifier() { - } - - virtual void binderDied(const wp<IBinder>& who); - }; - private: - ProCamera(); - - virtual void binderDied(const wp<IBinder>& who); - - // helper function to obtain camera service handle - static const sp<ICameraService>& getCameraService(); - - static sp<DeathNotifier> mDeathNotifier; - - sp<IProCameraUser> mCamera; - status_t mStatus; - - sp<ProCameraListener> mListener; - - friend class DeathNotifier; - - static Mutex mLock; - static sp<ICameraService> mCameraService; + ProCamera(int cameraId); class ProFrameListener : public CpuConsumer::FrameAvailableListener { public: @@ -324,7 +309,7 @@ private: StreamInfo& getStreamInfo(int streamId); - + friend class CameraBase; }; }; // namespace android diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp index 82fb637..9499712 100644 --- a/media/libstagefright/mpeg2ts/ESQueue.cpp +++ b/media/libstagefright/mpeg2ts/ESQueue.cpp @@ -536,7 +536,7 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitH264() { size_t nalSize; bool foundSlice = false; while ((err = getNextNALUnit(&data, &size, &nalStart, &nalSize)) == OK) { - CHECK_GT(nalSize, 0u); + if (nalSize == 0) continue; unsigned nalType = nalStart[0] & 0x1f; bool flush = false; diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index ec1c3f0..1a78b53 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -269,10 +269,14 @@ sp<ICamera> CameraService::connect( sp<IProCameraUser> CameraService::connect( const sp<IProCameraCallbacks>& cameraCb, - int cameraId) + int cameraId, + const String16& clientPackageName, + int clientUid) { int callingPid = getCallingPid(); + // TODO: use clientPackageName and clientUid with appOpsMangr + LOG1("CameraService::connectPro E (pid %d, id %d)", callingPid, cameraId); if (!mModule) { diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index b017505..d93aa73 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -25,6 +25,11 @@ #include <camera/ICameraService.h> #include <hardware/camera.h> +#include <camera/ICamera.h> +#include <camera/ICameraClient.h> +#include <camera/IProCameraUser.h> +#include <camera/IProCameraCallbacks.h> + /* This needs to be increased if we can have more cameras */ #define MAX_CAMERAS 2 @@ -60,7 +65,7 @@ public: virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient, int cameraId, const String16& clientPackageName, int clientUid); virtual sp<IProCameraUser> connect(const sp<IProCameraCallbacks>& cameraCb, - int cameraId); + int cameraId, const String16& clientPackageName, int clientUid); // Extra permissions checks virtual status_t onTransact(uint32_t code, const Parcel& data, |