summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camera/Android.mk1
-rw-r--r--camera/Camera.cpp126
-rw-r--r--camera/CameraBase.cpp237
-rw-r--r--camera/ICameraService.cpp15
-rw-r--r--camera/ProCamera.cpp153
-rw-r--r--include/camera/Camera.h81
-rw-r--r--include/camera/CameraBase.h117
-rw-r--r--include/camera/ICameraService.h13
-rw-r--r--include/camera/ProCamera.h65
-rw-r--r--services/camera/libcameraservice/CameraService.cpp6
-rw-r--r--services/camera/libcameraservice/CameraService.h7
11 files changed, 464 insertions, 357 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/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,