summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorEino-Ville Talvala <etalvala@google.com>2012-07-31 14:36:26 -0700
committerEino-Ville Talvala <etalvala@google.com>2012-08-02 16:51:48 -0700
commit3a609147811105d40766f8f8f5904bf71cb123cb (patch)
tree27cc2e751e60d6daf4960efe47a3bc035376887c /services
parent428b77a2b94b74665a47375b3fdb893b98d71269 (diff)
downloadframeworks_av-3a609147811105d40766f8f8f5904bf71cb123cb.zip
frameworks_av-3a609147811105d40766f8f8f5904bf71cb123cb.tar.gz
frameworks_av-3a609147811105d40766f8f8f5904bf71cb123cb.tar.bz2
Camera2: Check PIDs to ensure camera exclusive access.
Bug: 6243944 Change-Id: I4b36af2c92b7266a4aa896a2b048c56b6406cb9a
Diffstat (limited to 'services')
-rw-r--r--services/camera/libcameraservice/Camera2Client.cpp72
-rw-r--r--services/camera/libcameraservice/Camera2Client.h5
2 files changed, 69 insertions, 8 deletions
diff --git a/services/camera/libcameraservice/Camera2Client.cpp b/services/camera/libcameraservice/Camera2Client.cpp
index 62741d5..7e08907 100644
--- a/services/camera/libcameraservice/Camera2Client.cpp
+++ b/services/camera/libcameraservice/Camera2Client.cpp
@@ -52,7 +52,7 @@ Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
int clientPid):
Client(cameraService, cameraClient,
cameraId, cameraFacing, clientPid),
- mState(NOT_INITIALIZED),
+ mState(DISCONNECTED),
mPreviewStreamId(NO_STREAM),
mPreviewRequest(NULL),
mCaptureStreamId(NO_STREAM),
@@ -65,6 +65,15 @@ Camera2Client::Camera2Client(const sp<CameraService>& cameraService,
mDevice = new Camera2Device(cameraId);
}
+status_t Camera2Client::checkPid(const char* checkLocation) const {
+ int callingPid = getCallingPid();
+ if (callingPid == mClientPid) return NO_ERROR;
+
+ ALOGE("%s: attempt to use a locked camera from a different process"
+ " (old pid %d, new pid %d)", checkLocation, mClientPid, callingPid);
+ return PERMISSION_DENIED;
+}
+
status_t Camera2Client::initialize(camera_module_t *module)
{
ATRACE_CALL();
@@ -103,6 +112,8 @@ Camera2Client::~Camera2Client() {
mDestructionStarted = true;
+ // Rewrite mClientPid to allow shutdown by CameraService
+ mClientPid = getCallingPid();
disconnect();
}
@@ -317,7 +328,7 @@ status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
const char* Camera2Client::getStateName(State state) {
#define CASE_ENUM_TO_CHAR(x) case x: return(#x); break;
switch(state) {
- CASE_ENUM_TO_CHAR(NOT_INITIALIZED)
+ CASE_ENUM_TO_CHAR(DISCONNECTED)
CASE_ENUM_TO_CHAR(STOPPED)
CASE_ENUM_TO_CHAR(WAITING_FOR_PREVIEW_WINDOW)
CASE_ENUM_TO_CHAR(PREVIEW)
@@ -337,6 +348,8 @@ void Camera2Client::disconnect() {
ATRACE_CALL();
ALOGV("%s: E", __FUNCTION__);
Mutex::Autolock icl(mICameraLock);
+ status_t res;
+ if ( (res = checkPid(__FUNCTION__) ) != OK) return;
if (mDevice == 0) return;
@@ -359,6 +372,9 @@ void Camera2Client::disconnect() {
mRecordingStreamId = NO_STREAM;
}
+ mDevice.clear();
+ mState = DISCONNECTED;
+
CameraService::Client::disconnect();
}
@@ -426,6 +442,8 @@ status_t Camera2Client::setPreviewDisplay(
ATRACE_CALL();
ALOGV("%s: E", __FUNCTION__);
Mutex::Autolock icl(mICameraLock);
+ status_t res;
+ if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
sp<IBinder> binder;
sp<ANativeWindow> window;
@@ -442,6 +460,8 @@ status_t Camera2Client::setPreviewTexture(
ATRACE_CALL();
ALOGV("%s: E", __FUNCTION__);
Mutex::Autolock icl(mICameraLock);
+ status_t res;
+ if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
sp<IBinder> binder;
sp<ANativeWindow> window;
@@ -464,7 +484,7 @@ status_t Camera2Client::setPreviewWindowLocked(const sp<IBinder>& binder,
}
switch (mState) {
- case NOT_INITIALIZED:
+ case DISCONNECTED:
case RECORD:
case STILL_CAPTURE:
case VIDEO_SNAPSHOT:
@@ -513,12 +533,16 @@ status_t Camera2Client::setPreviewWindowLocked(const sp<IBinder>& binder,
void Camera2Client::setPreviewCallbackFlag(int flag) {
ATRACE_CALL();
Mutex::Autolock icl(mICameraLock);
+ status_t res;
+ if ( (res = checkPid(__FUNCTION__) ) != OK) return;
}
status_t Camera2Client::startPreview() {
ATRACE_CALL();
ALOGV("%s: E", __FUNCTION__);
Mutex::Autolock icl(mICameraLock);
+ status_t res;
+ if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
return startPreviewLocked();
}
@@ -586,13 +610,15 @@ void Camera2Client::stopPreview() {
ATRACE_CALL();
ALOGV("%s: E", __FUNCTION__);
Mutex::Autolock icl(mICameraLock);
+ status_t res;
+ if ( (res = checkPid(__FUNCTION__) ) != OK) return;
stopPreviewLocked();
}
void Camera2Client::stopPreviewLocked() {
ATRACE_CALL();
switch (mState) {
- case NOT_INITIALIZED:
+ case DISCONNECTED:
ALOGE("%s: Camera %d: Call before initialized",
__FUNCTION__, mCameraId);
break;
@@ -619,12 +645,18 @@ void Camera2Client::stopPreviewLocked() {
bool Camera2Client::previewEnabled() {
ATRACE_CALL();
Mutex::Autolock icl(mICameraLock);
+ status_t res;
+ if ( (res = checkPid(__FUNCTION__) ) != OK) return false;
+
return mState == PREVIEW;
}
status_t Camera2Client::storeMetaDataInBuffers(bool enabled) {
ATRACE_CALL();
Mutex::Autolock icl(mICameraLock);
+ status_t res;
+ if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
+
switch (mState) {
case RECORD:
case VIDEO_SNAPSHOT:
@@ -647,6 +679,8 @@ status_t Camera2Client::startRecording() {
ALOGV("%s: E", __FUNCTION__);
Mutex::Autolock icl(mICameraLock);
status_t res;
+ if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
+
switch (mState) {
case STOPPED:
res = startPreviewLocked();
@@ -724,6 +758,8 @@ void Camera2Client::stopRecording() {
ALOGV("%s: E", __FUNCTION__);
Mutex::Autolock icl(mICameraLock);
status_t res;
+ if ( (res = checkPid(__FUNCTION__) ) != OK) return;
+
switch (mState) {
case RECORD:
// OK to stop
@@ -756,16 +792,19 @@ void Camera2Client::stopRecording() {
bool Camera2Client::recordingEnabled() {
ATRACE_CALL();
Mutex::Autolock icl(mICameraLock);
+ if ( checkPid(__FUNCTION__) != OK) return false;
+
return (mState == RECORD || mState == VIDEO_SNAPSHOT);
}
void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
ATRACE_CALL();
Mutex::Autolock icl(mICameraLock);
+ status_t res;
+ if ( checkPid(__FUNCTION__) != OK) return;
// Make sure this is for the current heap
ssize_t offset;
size_t size;
- status_t res;
sp<IMemoryHeap> heap = mem->getMemory(&offset, &size);
if (heap->getHeapID() != mRecordingHeap->mHeap->getHeapID()) {
ALOGW("%s: Camera %d: Mismatched heap ID, ignoring release "
@@ -797,12 +836,18 @@ void Camera2Client::releaseRecordingFrame(const sp<IMemory>& mem) {
status_t Camera2Client::autoFocus() {
ATRACE_CALL();
Mutex::Autolock icl(mICameraLock);
+ status_t res;
+ if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
+
return OK;
}
status_t Camera2Client::cancelAutoFocus() {
ATRACE_CALL();
Mutex::Autolock icl(mICameraLock);
+ status_t res;
+ if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
+
return OK;
}
@@ -810,9 +855,10 @@ status_t Camera2Client::takePicture(int msgType) {
ATRACE_CALL();
Mutex::Autolock icl(mICameraLock);
status_t res;
+ if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
switch (mState) {
- case NOT_INITIALIZED:
+ case DISCONNECTED:
case STOPPED:
case WAITING_FOR_PREVIEW_WINDOW:
ALOGE("%s: Camera %d: Cannot take picture without preview enabled",
@@ -917,8 +963,10 @@ status_t Camera2Client::setParameters(const String8& params) {
ATRACE_CALL();
ALOGV("%s: E", __FUNCTION__);
Mutex::Autolock icl(mICameraLock);
- LockedParameters::Key k(mParameters);
status_t res;
+ if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
+
+ LockedParameters::Key k(mParameters);
CameraParameters newParams(params);
@@ -1457,6 +1505,7 @@ status_t Camera2Client::setParameters(const String8& params) {
String8 Camera2Client::getParameters() const {
ATRACE_CALL();
Mutex::Autolock icl(mICameraLock);
+ if ( checkPid(__FUNCTION__) != OK) return String8();
LockedParameters::ReadKey k(mParameters);
@@ -1467,6 +1516,8 @@ String8 Camera2Client::getParameters() const {
status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
ATRACE_CALL();
Mutex::Autolock icl(mICameraLock);
+ status_t res;
+ if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
ALOGV("%s: Camera %d: Command %d (%d, %d)", __FUNCTION__, mCameraId,
cmd, arg1, arg2);
@@ -1486,6 +1537,13 @@ status_t Camera2Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
}
k.mParameters.previewTransform = transform;
return OK;
+ } else if (cmd == CAMERA_CMD_PING) {
+ // Always ping back if access is proper and device is alive
+ if (mState != DISCONNECTED) {
+ return OK;
+ } else {
+ return NO_INIT;
+ }
}
ALOGE("%s: Camera %d: Unimplemented command %d (%d, %d)", __FUNCTION__,
diff --git a/services/camera/libcameraservice/Camera2Client.h b/services/camera/libcameraservice/Camera2Client.h
index 3494114..8ae16a4 100644
--- a/services/camera/libcameraservice/Camera2Client.h
+++ b/services/camera/libcameraservice/Camera2Client.h
@@ -72,7 +72,7 @@ public:
private:
enum State {
- NOT_INITIALIZED,
+ DISCONNECTED,
STOPPED,
WAITING_FOR_PREVIEW_WINDOW,
PREVIEW,
@@ -302,6 +302,9 @@ private:
/** Utility members */
+ // Verify that caller is the owner of the camera
+ status_t checkPid(const char *checkLocation) const;
+
// Utility class for managing a set of IMemory blocks
class Camera2Heap : public RefBase {
public: