Loading camera/libcameraservice/CameraService.cpp +39 −12 Original line number Original line Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <media/AudioSystem.h> #include <media/AudioSystem.h> #include "CameraService.h" #include "CameraService.h" #include <cutils/atomic.h> #include <cutils/properties.h> #include <cutils/properties.h> namespace android { namespace android { Loading Loading @@ -81,6 +82,7 @@ CameraService::CameraService() : BnCameraService() BnCameraService() { { LOGI("CameraService started: pid=%d", getpid()); LOGI("CameraService started: pid=%d", getpid()); mUsers = 0; } } CameraService::~CameraService() CameraService::~CameraService() Loading Loading @@ -113,7 +115,7 @@ sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient) "(old pid %d, old client %p)", "(old pid %d, old client %p)", callingPid, cameraClient->asBinder().get(), callingPid, cameraClient->asBinder().get(), currentClient->mClientPid, currentCameraClient->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!"); LOGD("The old client is dead!"); } } return client; 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...", LOGD("New client (pid %d) connecting, old reference was dangling...", callingPid); callingPid); mClient.clear(); 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); 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) static sp<MediaPlayer> newMediaPlayer(const char *file) { { sp<MediaPlayer> mp = new MediaPlayer(); sp<MediaPlayer> mp = new MediaPlayer(); Loading Loading @@ -209,6 +229,7 @@ CameraService::Client::Client(const sp<CameraService>& cameraService, // Callback is disabled by default // Callback is disabled by default mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP; mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP; cameraService->incUsers(); LOGD("Client::Client X (pid %d)", callingPid); LOGD("Client::Client X (pid %d)", callingPid); } } Loading Loading @@ -365,8 +386,12 @@ void CameraService::Client::disconnect() return; 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); mCameraService->removeClient(mCameraClient); if (mHardware != 0) { LOGD("hardware teardown"); LOGD("hardware teardown"); // Before destroying mHardware, we must make sure it's in the // Before destroying mHardware, we must make sure it's in the // idle state. // idle state. Loading @@ -375,8 +400,10 @@ void CameraService::Client::disconnect() mHardware->cancelPicture(true, true, true); mHardware->cancelPicture(true, true, true); // Release the hardware resources. // Release the hardware resources. mHardware->release(); mHardware->release(); } mHardware.clear(); mHardware.clear(); mCameraService->decUsers(); LOGD("Client::disconnect() X (pid %d)", callingPid); LOGD("Client::disconnect() X (pid %d)", callingPid); } } Loading camera/libcameraservice/CameraService.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -194,6 +194,11 @@ private: CameraService(); CameraService(); virtual ~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; mutable Mutex mLock; wp<Client> mClient; wp<Client> mClient; Loading Loading
camera/libcameraservice/CameraService.cpp +39 −12 Original line number Original line Diff line number Diff line Loading @@ -32,6 +32,7 @@ #include <media/AudioSystem.h> #include <media/AudioSystem.h> #include "CameraService.h" #include "CameraService.h" #include <cutils/atomic.h> #include <cutils/properties.h> #include <cutils/properties.h> namespace android { namespace android { Loading Loading @@ -81,6 +82,7 @@ CameraService::CameraService() : BnCameraService() BnCameraService() { { LOGI("CameraService started: pid=%d", getpid()); LOGI("CameraService started: pid=%d", getpid()); mUsers = 0; } } CameraService::~CameraService() CameraService::~CameraService() Loading Loading @@ -113,7 +115,7 @@ sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient) "(old pid %d, old client %p)", "(old pid %d, old client %p)", callingPid, cameraClient->asBinder().get(), callingPid, cameraClient->asBinder().get(), currentClient->mClientPid, currentCameraClient->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!"); LOGD("The old client is dead!"); } } return client; 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...", LOGD("New client (pid %d) connecting, old reference was dangling...", callingPid); callingPid); mClient.clear(); 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); 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) static sp<MediaPlayer> newMediaPlayer(const char *file) { { sp<MediaPlayer> mp = new MediaPlayer(); sp<MediaPlayer> mp = new MediaPlayer(); Loading Loading @@ -209,6 +229,7 @@ CameraService::Client::Client(const sp<CameraService>& cameraService, // Callback is disabled by default // Callback is disabled by default mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP; mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP; cameraService->incUsers(); LOGD("Client::Client X (pid %d)", callingPid); LOGD("Client::Client X (pid %d)", callingPid); } } Loading Loading @@ -365,8 +386,12 @@ void CameraService::Client::disconnect() return; 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); mCameraService->removeClient(mCameraClient); if (mHardware != 0) { LOGD("hardware teardown"); LOGD("hardware teardown"); // Before destroying mHardware, we must make sure it's in the // Before destroying mHardware, we must make sure it's in the // idle state. // idle state. Loading @@ -375,8 +400,10 @@ void CameraService::Client::disconnect() mHardware->cancelPicture(true, true, true); mHardware->cancelPicture(true, true, true); // Release the hardware resources. // Release the hardware resources. mHardware->release(); mHardware->release(); } mHardware.clear(); mHardware.clear(); mCameraService->decUsers(); LOGD("Client::disconnect() X (pid %d)", callingPid); LOGD("Client::disconnect() X (pid %d)", callingPid); } } Loading
camera/libcameraservice/CameraService.h +5 −0 Original line number Original line Diff line number Diff line Loading @@ -194,6 +194,11 @@ private: CameraService(); CameraService(); virtual ~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; mutable Mutex mLock; wp<Client> mClient; wp<Client> mClient; Loading