summaryrefslogtreecommitdiffstats
path: root/camera/libcameraservice
diff options
context:
space:
mode:
Diffstat (limited to 'camera/libcameraservice')
-rw-r--r--camera/libcameraservice/CameraHardwareStub.cpp4
-rw-r--r--camera/libcameraservice/CameraHardwareStub.h1
-rw-r--r--camera/libcameraservice/CameraService.cpp62
-rw-r--r--camera/libcameraservice/CameraService.h19
4 files changed, 76 insertions, 10 deletions
diff --git a/camera/libcameraservice/CameraHardwareStub.cpp b/camera/libcameraservice/CameraHardwareStub.cpp
index ea21af82b..3d6b0b1ea 100644
--- a/camera/libcameraservice/CameraHardwareStub.cpp
+++ b/camera/libcameraservice/CameraHardwareStub.cpp
@@ -183,6 +183,10 @@ void CameraHardwareStub::stopPreview()
mPreviewThread.clear();
}
+bool CameraHardwareStub::previewEnabled() {
+ return mPreviewThread != 0;
+}
+
// ---------------------------------------------------------------------------
int CameraHardwareStub::beginAutoFocusThread(void *cookie)
diff --git a/camera/libcameraservice/CameraHardwareStub.h b/camera/libcameraservice/CameraHardwareStub.h
index 5b445d31c..9f5ddf13e 100644
--- a/camera/libcameraservice/CameraHardwareStub.h
+++ b/camera/libcameraservice/CameraHardwareStub.h
@@ -33,6 +33,7 @@ public:
virtual status_t startPreview(preview_callback cb, void* user);
virtual void stopPreview();
+ virtual bool previewEnabled();
virtual status_t autoFocus(autofocus_callback, void *user);
virtual status_t takePicture(shutter_callback,
raw_callback,
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index 800ffa48a..33987c360 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -107,7 +107,7 @@ sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient)
}
// create a new Client object
- sp<Client> client = new Client(this, cameraClient);
+ sp<Client> client = new Client(this, cameraClient, IPCThreadState::self()->getCallingPid());
mClient = client;
#if DEBUG_CLIENT_REFERENCES
// Enable tracking for this object, and track increments and decrements of
@@ -151,10 +151,12 @@ void CameraService::removeClient(const sp<ICameraClient>& cameraClient)
}
CameraService::Client::Client(const sp<CameraService>& cameraService,
- const sp<ICameraClient>& cameraClient) :
- mCameraService(cameraService), mCameraClient(cameraClient), mHardware(0)
+ const sp<ICameraClient>& cameraClient, pid_t clientPid)
{
LOGD("Client E constructor");
+ mCameraService = cameraService;
+ mCameraClient = cameraClient;
+ mClientPid = clientPid;
mHardware = openCameraHardware();
// Callback is disabled by default
@@ -162,12 +164,36 @@ CameraService::Client::Client(const sp<CameraService>& cameraService,
LOGD("Client X constructor");
}
+status_t CameraService::Client::checkPid()
+{
+ // zero means the interface is not locked down
+ if (mClientPid == 0) return NO_ERROR;
+ return (int) mClientPid == IPCThreadState::self()->getCallingPid() ? NO_ERROR : -EBUSY;
+}
+
+status_t CameraService::Client::lock()
+{
+ // lock camera to this client
+ status_t result = checkPid();
+ if (result == NO_ERROR) mClientPid = IPCThreadState::self()->getCallingPid();
+ return result;
+}
+
+status_t CameraService::Client::unlock()
+{
+ // allow anyone to use camera
+ status_t result = checkPid();
+ if (result == NO_ERROR) mClientPid = 0;
+ return result;
+}
+
status_t CameraService::Client::connect(const sp<ICameraClient>& client)
{
- // remvoe old client
- LOGD("connect (new client)");
+ // remove old client
+ LOGV("connect new client to existing camera");
Mutex::Autolock _l(mLock);
mCameraClient = client;
+ mClientPid = IPCThreadState::self()->getCallingPid();
mFrameCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
return NO_ERROR;
}
@@ -209,6 +235,7 @@ void CameraService::Client::disconnect()
{
LOGD("Client E disconnect");
Mutex::Autolock lock(mLock);
+ if (checkPid() != NO_ERROR) return;
mCameraService->removeClient(mCameraClient);
if (mHardware != 0) {
// Before destroying mHardware, we must make sure it's in the
@@ -228,6 +255,8 @@ status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface)
{
LOGD("setPreviewDisplay(%p)", surface.get());
Mutex::Autolock lock(mLock);
+ status_t result = checkPid();
+ if (result != NO_ERROR) return result;
Mutex::Autolock surfaceLock(mSurfaceLock);
// asBinder() is safe on NULL (returns NULL)
if (surface->asBinder() != mSurface->asBinder()) {
@@ -245,6 +274,7 @@ status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface)
void CameraService::Client::setFrameCallbackFlag(int frame_callback_flag)
{
Mutex::Autolock lock(mLock);
+ if (checkPid() != NO_ERROR) return;
mFrameCallbackFlag = frame_callback_flag;
}
@@ -258,6 +288,8 @@ status_t CameraService::Client::startPreview()
*/
Mutex::Autolock lock(mLock);
+ status_t result = checkPid();
+ if (result != NO_ERROR) return result;
if (mHardware == 0) {
LOGE("mHardware is NULL, returning.");
@@ -269,14 +301,15 @@ status_t CameraService::Client::startPreview()
return INVALID_OPERATION;
}
+ // do nothing if preview is already started
+ if (mHardware->previewEnabled()) return NO_ERROR;
+
// XXX: This needs to be improved. remove all hardcoded stuff
int w, h;
CameraParameters params(mHardware->getParameters());
params.getPreviewSize(&w, &h);
- mSurface->unregisterBuffers();
-
#if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
debug_frame_cnt = 0;
#endif
@@ -284,6 +317,7 @@ status_t CameraService::Client::startPreview()
status_t ret = mHardware->startPreview(previewCallback,
mCameraService.get());
if (ret == NO_ERROR) {
+ mSurface->unregisterBuffers();
mSurface->registerBuffers(w,h,w,h,
PIXEL_FORMAT_YCbCr_420_SP,
mHardware->getPreviewHeap());
@@ -300,6 +334,7 @@ void CameraService::Client::stopPreview()
LOGD("stopPreview()");
Mutex::Autolock lock(mLock);
+ if (checkPid() != NO_ERROR) return;
if (mHardware == 0) {
LOGE("mHardware is NULL, returning.");
@@ -315,6 +350,13 @@ void CameraService::Client::stopPreview()
mPreviewBuffer.clear();
}
+bool CameraService::Client::previewEnabled()
+{
+ Mutex::Autolock lock(mLock);
+ if (mHardware == 0) return false;
+ return mHardware->previewEnabled();
+}
+
// Safely retrieves a strong pointer to the client during a hardware callback.
sp<CameraService::Client> CameraService::Client::getClientFromCookie(void* user)
{
@@ -424,6 +466,8 @@ status_t CameraService::Client::autoFocus()
LOGV("autoFocus");
Mutex::Autolock lock(mLock);
+ status_t result = checkPid();
+ if (result != NO_ERROR) return result;
if (mHardware == 0) {
LOGE("mHardware is NULL, returning.");
@@ -440,6 +484,8 @@ status_t CameraService::Client::takePicture()
LOGD("takePicture");
Mutex::Autolock lock(mLock);
+ status_t result = checkPid();
+ if (result != NO_ERROR) return result;
if (mHardware == 0) {
LOGE("mHardware is NULL, returning.");
@@ -580,6 +626,8 @@ status_t CameraService::Client::setParameters(const String8& params)
LOGD("setParameters(%s)", params.string());
Mutex::Autolock lock(mLock);
+ status_t result = checkPid();
+ if (result != NO_ERROR) return result;
if (mHardware == 0) {
LOGE("mHardware is NULL, returning.");
diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h
index b225aa9f3..cd8c1e9a4 100644
--- a/camera/libcameraservice/CameraService.h
+++ b/camera/libcameraservice/CameraService.h
@@ -73,6 +73,12 @@ private:
// connect new client with existing camera remote
virtual status_t connect(const sp<ICameraClient>& client);
+ // prevent other processes from using this ICamera interface
+ virtual status_t lock();
+
+ // allow other processes to use this ICamera interface
+ virtual status_t unlock();
+
// pass the buffered ISurface to the camera service
virtual status_t setPreviewDisplay(const sp<ISurface>& surface);
@@ -86,6 +92,9 @@ private:
// stop preview mode
virtual void stopPreview();
+ // get preview state
+ virtual bool previewEnabled();
+
// auto focus
virtual status_t autoFocus();
@@ -103,11 +112,14 @@ private:
private:
friend class CameraService;
- Client( const sp<CameraService>& cameraService,
- const sp<ICameraClient>& cameraClient);
+ Client(const sp<CameraService>& cameraService,
+ const sp<ICameraClient>& cameraClient,
+ pid_t clientPid);
Client();
virtual ~Client();
+ status_t checkPid();
+
static void previewCallback(const sp<IMemory>& mem, void* user);
static void shutterCallback(void *user);
static void yuvPictureCallback(const sp<IMemory>& mem, void* user);
@@ -132,7 +144,7 @@ private:
// by the CameraHardwareInterface callback, and needs to
// access mSurface. It cannot hold mLock, however, because
// stopPreview() may be holding that lock while attempting
- // top stop preview, and stopPreview itself will block waiting
+ // to stop preview, and stopPreview itself will block waiting
// for a callback from CameraHardwareInterface. If this
// happens, it will cause a deadlock.
mutable Mutex mSurfaceLock;
@@ -146,6 +158,7 @@ private:
// they don't need to be protected by a lock
sp<ICameraClient> mCameraClient;
sp<CameraHardwareInterface> mHardware;
+ pid_t mClientPid;
};
// ----------------------------------------------------------------------------