From 71d714ccbf03948d67ab6cebad49703160e5895e Mon Sep 17 00:00:00 2001 From: James Dong Date: Wed, 9 Jun 2010 15:57:48 -0700 Subject: [PATCH] Remove the lock/unlock workaround from CameraService bug - 2677772 Change-Id: I7c996daad8b3bfc89e9fa2d655dc18c9a5c68f2f --- camera/libcameraservice/CameraService.cpp | 5 +--- .../StagefrightRecorder.cpp | 25 +++++++++++++------ media/libstagefright/CameraSource.cpp | 20 ++++++++++++--- 3 files changed, 35 insertions(+), 15 deletions(-) diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp index 4f684b7ba3d3a..690169af8a82b 100644 --- a/camera/libcameraservice/CameraService.cpp +++ b/camera/libcameraservice/CameraService.cpp @@ -371,10 +371,7 @@ CameraService::Client::~Client() { status_t CameraService::Client::checkPid() const { int callingPid = getCallingPid(); if (callingPid == mClientPid) return NO_ERROR; - if (callingPid == getpid()) { - LOGW("FIXME: use camera from mediaserver without permission."); - return NO_ERROR; - } + LOGW("attempt to use a locked camera from a different process" " (old pid %d, new pid %d)", mClientPid, callingPid); return EBUSY; diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp index 1a684a96dcd43..2f3b075cfb48d 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -114,25 +114,27 @@ status_t StagefrightRecorder::setVideoFrameRate(int frames_per_second) { } status_t StagefrightRecorder::setCamera(const sp &camera) { - LOGV("setCamera: pid %d pid %d", IPCThreadState::self()->getCallingPid(), getpid()); + LOGV("setCamera"); if (camera == 0) { LOGE("camera is NULL"); return UNKNOWN_ERROR; } - mFlags &= ~ FLAGS_SET_CAMERA | FLAGS_HOT_CAMERA; + int64_t token = IPCThreadState::self()->clearCallingIdentity(); + mFlags &= ~FLAGS_HOT_CAMERA; mCamera = Camera::create(camera); if (mCamera == 0) { LOGE("Unable to connect to camera"); + IPCThreadState::self()->restoreCallingIdentity(token); return UNKNOWN_ERROR; } LOGV("Connected to camera"); - mFlags |= FLAGS_SET_CAMERA; if (mCamera->previewEnabled()) { LOGV("camera is hot"); mFlags |= FLAGS_HOT_CAMERA; } + IPCThreadState::self()->restoreCallingIdentity(token); return OK; } @@ -584,7 +586,12 @@ status_t StagefrightRecorder::startMPEG4Recording() { } if (mVideoSource == VIDEO_SOURCE_DEFAULT || mVideoSource == VIDEO_SOURCE_CAMERA) { - CHECK(mCamera != NULL); + + int64_t token = IPCThreadState::self()->clearCallingIdentity(); + if (mCamera == 0) { + mCamera = Camera::connect(0); + mCamera->lock(); + } // Set the actual video recording frame size CameraParameters params(mCamera->getParameters()); @@ -601,6 +608,7 @@ status_t StagefrightRecorder::startMPEG4Recording() { frameHeight < 0 || frameHeight != mVideoHeight) { LOGE("Failed to set the video frame size to %dx%d", mVideoWidth, mVideoHeight); + IPCThreadState::self()->restoreCallingIdentity(token); return UNKNOWN_ERROR; } @@ -612,6 +620,7 @@ status_t StagefrightRecorder::startMPEG4Recording() { } CHECK_EQ(OK, mCamera->setPreviewDisplay(mPreviewSurface)); + IPCThreadState::self()->restoreCallingIdentity(token); sp cameraSource = CameraSource::CreateFromCamera(mCamera); @@ -698,14 +707,14 @@ status_t StagefrightRecorder::close() { stop(); if (mCamera != 0) { + int64_t token = IPCThreadState::self()->clearCallingIdentity(); if ((mFlags & FLAGS_HOT_CAMERA) == 0) { LOGV("Camera was cold when we started, stopping preview"); mCamera->stopPreview(); } - if (mFlags & FLAGS_SET_CAMERA) { - LOGV("Unlocking camera"); - mCamera->unlock(); - } + mCamera->unlock(); + mCamera = NULL; + IPCThreadState::self()->restoreCallingIdentity(token); mFlags = 0; } return OK; diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp index 67759c05e92b8..0ab76b3f22dbb 100644 --- a/media/libstagefright/CameraSource.cpp +++ b/media/libstagefright/CameraSource.cpp @@ -19,7 +19,7 @@ #include #include - +#include #include #include #include @@ -125,7 +125,11 @@ CameraSource::CameraSource(const sp &camera) mNumFramesDropped(0), mCollectStats(false), mStarted(false) { + + int64_t token = IPCThreadState::self()->clearCallingIdentity(); String8 s = mCamera->getParameters(); + IPCThreadState::self()->restoreCallingIdentity(token); + printf("params: \"%s\"\n", s.string()); int32_t width, height, stride, sliceHeight; @@ -166,8 +170,11 @@ status_t CameraSource::start(MetaData *) { && (!strcmp(value, "1") || !strcasecmp(value, "true"))) { mCollectStats = true; } + + int64_t token = IPCThreadState::self()->clearCallingIdentity(); mCamera->setListener(new CameraSourceListener(this)); CHECK_EQ(OK, mCamera->startRecording()); + IPCThreadState::self()->restoreCallingIdentity(token); mStarted = true; return OK; @@ -179,16 +186,17 @@ status_t CameraSource::stop() { mStarted = false; mFrameAvailableCondition.signal(); + int64_t token = IPCThreadState::self()->clearCallingIdentity(); mCamera->setListener(NULL); mCamera->stopRecording(); - releaseQueuedFrames(); - while (!mFramesBeingEncoded.empty()) { LOGI("Waiting for outstanding frames being encoded: %d", mFramesBeingEncoded.size()); mFrameCompleteCondition.wait(mLock); } + mCamera = NULL; + IPCThreadState::self()->restoreCallingIdentity(token); if (mCollectStats) { LOGI("Frames received/encoded/dropped: %d/%d/%d in %lld us", @@ -219,7 +227,11 @@ void CameraSource::signalBufferReturned(MediaBuffer *buffer) { for (List >::iterator it = mFramesBeingEncoded.begin(); it != mFramesBeingEncoded.end(); ++it) { if ((*it)->pointer() == buffer->data()) { + + int64_t token = IPCThreadState::self()->clearCallingIdentity(); mCamera->releaseRecordingFrame((*it)); + IPCThreadState::self()->restoreCallingIdentity(token); + mFramesBeingEncoded.erase(it); ++mNumFramesEncoded; buffer->setObserver(0); @@ -273,7 +285,9 @@ void CameraSource::dataCallbackTimestamp(int64_t timestampUs, LOGV("dataCallbackTimestamp: timestamp %lld us", timestampUs); Mutex::Autolock autoLock(mLock); if (!mStarted) { + int64_t token = IPCThreadState::self()->clearCallingIdentity(); mCamera->releaseRecordingFrame(data); + IPCThreadState::self()->restoreCallingIdentity(token); ++mNumFramesReceived; ++mNumFramesDropped; return;