Loading camera/libcameraservice/CameraService.cpp +39 −12 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <media/AudioSystem.h> #include "CameraService.h" #include <cutils/atomic.h> #include <cutils/properties.h> namespace android { Loading Loading @@ -81,6 +82,7 @@ CameraService::CameraService() : BnCameraService() { LOGI("CameraService started: pid=%d", getpid()); mUsers = 0; } CameraService::~CameraService() Loading Loading @@ -113,7 +115,7 @@ sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient) "(old pid %d, old client %p)", callingPid, cameraClient->asBinder().get(), currentClient->mClientPid, currentCameraClient->asBinder().get()); if (kill(currentClient->mClientPid, 0) == ESRCH) { if (kill(currentClient->mClientPid, 0) == -1 && errno == ESRCH) { LOGD("The old client is dead!"); } return client; Loading @@ -123,6 +125,10 @@ sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient) LOGD("New client (pid %d) connecting, old reference was dangling...", callingPid); mClient.clear(); if (mUsers > 0) { LOGD("Still have client, rejected"); return client; } } } Loading Loading @@ -174,6 +180,20 @@ void CameraService::removeClient(const sp<ICameraClient>& cameraClient) LOGD("removeClient (pid %d) done", callingPid); } // The reason we need this count is a new CameraService::connect() request may // come in while the previous Client's destructor has not been run or is still // running. If the last strong reference of the previous Client is gone but // destructor has not been run, we should not allow the new Client to be created // because we need to wait for the previous Client to tear down the hardware // first. void CameraService::incUsers() { android_atomic_inc(&mUsers); } void CameraService::decUsers() { android_atomic_dec(&mUsers); } static sp<MediaPlayer> newMediaPlayer(const char *file) { sp<MediaPlayer> mp = new MediaPlayer(); Loading Loading @@ -209,6 +229,7 @@ CameraService::Client::Client(const sp<CameraService>& cameraService, // Callback is disabled by default mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP; cameraService->incUsers(); LOGD("Client::Client X (pid %d)", callingPid); } Loading Loading @@ -365,8 +386,12 @@ void CameraService::Client::disconnect() return; } // Make sure disconnect() is done once and once only, whether it is called // from the user directly, or called by the destructor. if (mHardware == 0) return; mCameraService->removeClient(mCameraClient); if (mHardware != 0) { LOGD("hardware teardown"); // Before destroying mHardware, we must make sure it's in the // idle state. Loading @@ -375,8 +400,10 @@ void CameraService::Client::disconnect() mHardware->cancelPicture(true, true, true); // Release the hardware resources. mHardware->release(); } mHardware.clear(); mCameraService->decUsers(); LOGD("Client::disconnect() X (pid %d)", callingPid); } Loading camera/libcameraservice/CameraService.h +5 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,11 @@ private: CameraService(); virtual ~CameraService(); // We use a count for number of clients (shoule only be 0 or 1). volatile int32_t mUsers; virtual void incUsers(); virtual void decUsers(); mutable Mutex mLock; wp<Client> mClient; Loading Loading
camera/libcameraservice/CameraService.cpp +39 −12 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <media/AudioSystem.h> #include "CameraService.h" #include <cutils/atomic.h> #include <cutils/properties.h> namespace android { Loading Loading @@ -81,6 +82,7 @@ CameraService::CameraService() : BnCameraService() { LOGI("CameraService started: pid=%d", getpid()); mUsers = 0; } CameraService::~CameraService() Loading Loading @@ -113,7 +115,7 @@ sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient) "(old pid %d, old client %p)", callingPid, cameraClient->asBinder().get(), currentClient->mClientPid, currentCameraClient->asBinder().get()); if (kill(currentClient->mClientPid, 0) == ESRCH) { if (kill(currentClient->mClientPid, 0) == -1 && errno == ESRCH) { LOGD("The old client is dead!"); } return client; Loading @@ -123,6 +125,10 @@ sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient) LOGD("New client (pid %d) connecting, old reference was dangling...", callingPid); mClient.clear(); if (mUsers > 0) { LOGD("Still have client, rejected"); return client; } } } Loading Loading @@ -174,6 +180,20 @@ void CameraService::removeClient(const sp<ICameraClient>& cameraClient) LOGD("removeClient (pid %d) done", callingPid); } // The reason we need this count is a new CameraService::connect() request may // come in while the previous Client's destructor has not been run or is still // running. If the last strong reference of the previous Client is gone but // destructor has not been run, we should not allow the new Client to be created // because we need to wait for the previous Client to tear down the hardware // first. void CameraService::incUsers() { android_atomic_inc(&mUsers); } void CameraService::decUsers() { android_atomic_dec(&mUsers); } static sp<MediaPlayer> newMediaPlayer(const char *file) { sp<MediaPlayer> mp = new MediaPlayer(); Loading Loading @@ -209,6 +229,7 @@ CameraService::Client::Client(const sp<CameraService>& cameraService, // Callback is disabled by default mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP; cameraService->incUsers(); LOGD("Client::Client X (pid %d)", callingPid); } Loading Loading @@ -365,8 +386,12 @@ void CameraService::Client::disconnect() return; } // Make sure disconnect() is done once and once only, whether it is called // from the user directly, or called by the destructor. if (mHardware == 0) return; mCameraService->removeClient(mCameraClient); if (mHardware != 0) { LOGD("hardware teardown"); // Before destroying mHardware, we must make sure it's in the // idle state. Loading @@ -375,8 +400,10 @@ void CameraService::Client::disconnect() mHardware->cancelPicture(true, true, true); // Release the hardware resources. mHardware->release(); } mHardware.clear(); mCameraService->decUsers(); LOGD("Client::disconnect() X (pid %d)", callingPid); } Loading
camera/libcameraservice/CameraService.h +5 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,11 @@ private: CameraService(); virtual ~CameraService(); // We use a count for number of clients (shoule only be 0 or 1). volatile int32_t mUsers; virtual void incUsers(); virtual void decUsers(); mutable Mutex mLock; wp<Client> mClient; Loading