• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

frameworks/av


Commit MetaInfo

修訂b7c2cf5d34843dcaf43053acc9da91cccaf122ac (tree)
時間2019-10-25 07:51:05
作者Jayant Chowdhary <jchowdhary@goog...>
CommiterJayant Chowdhary

Log Message

cameraserver: Avoiding deadlocks while calling isPublicallyHiddenSecureCamera().

The following scenario can occur:

T1 serving Client A's disconnect() call:
T2 : serving Client B's connect() call
T2 : CameraProviderManager::openSession() locks mInterfaceMutex and waits on open() HAL
interface call
T1: updateStatus() locks mStatusListenerMutex
T1: CameraProviderManager::isPublicallyHiddenSecureCamera() waits
on mInterfaceMutex
T2: while waiting on open(), gets a torchModeStatus() callback from the camera HAL
T2: onStatusChanged()
T2: broadcastTorchModeStatus() which waits on mStatusListenerMutex

As a result there's a possible circular hold and wait between T1 and T2.

We cache isPublicallyHiddenSecureCamera in CameraState. That doesn't completely
avoid having to hold mInterfaceLock while calling isPublicallyHiddenSecureCamera() in CameraService
(cache updates), instead it reduces it. We instead need to hold mCameraStates lock which has a
smaller scope.

Bug: 141756275

Test: CTS
Test: GCA (sanity)

Merged-In: I8562c83478b1fe8fbda7c85f97b995985666918d
Merged-In: I4a697c1eaccc3603007be4a595febea981fbeb64
Change-Id: Ie5508afb126a874f76fbbfc2dd19ef79ae6255e0
(cherry picked from commit fd39db81e44e191baa476a579de6cc2618de025a)
Signed-off-by: Jayant Chowdhary <jchowdhary@google.com>

Change Summary

差異

--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -256,6 +256,15 @@ void CameraService::onNewProviderRegistered() {
256256 enumerateProviders();
257257 }
258258
259+bool CameraService::isPublicallyHiddenSecureCamera(const String8& cameraId) {
260+ auto state = getCameraState(cameraId);
261+ if (state != nullptr) {
262+ return state->isPublicallyHiddenSecureCamera();
263+ }
264+ // Hidden physical camera ids won't have CameraState
265+ return mCameraProviderManager->isPublicallyHiddenSecureCamera(cameraId.c_str());
266+}
267+
259268 void CameraService::updateCameraNumAndIds() {
260269 Mutex::Autolock l(mServiceLock);
261270 mNumberOfCameras = mCameraProviderManager->getCameraCount();
@@ -271,6 +280,8 @@ void CameraService::addStates(const String8 id) {
271280 ALOGE("Failed to query device resource cost: %s (%d)", strerror(-res), res);
272281 return;
273282 }
283+ bool isPublicallyHiddenSecureCamera =
284+ mCameraProviderManager->isPublicallyHiddenSecureCamera(id.string());
274285 std::set<String8> conflicting;
275286 for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
276287 conflicting.emplace(String8(cost.conflictingDevices[i].c_str()));
@@ -279,7 +290,8 @@ void CameraService::addStates(const String8 id) {
279290 {
280291 Mutex::Autolock lock(mCameraStatesLock);
281292 mCameraStates.emplace(id, std::make_shared<CameraState>(id, cost.resourceCost,
282- conflicting));
293+ conflicting,
294+ isPublicallyHiddenSecureCamera));
283295 }
284296
285297 if (mFlashlight->hasFlashUnit(id)) {
@@ -517,8 +529,16 @@ Status CameraService::getCameraCharacteristics(const String16& cameraId,
517529 "Camera subsystem is not available");;
518530 }
519531
520- Status ret{};
532+ if (shouldRejectHiddenCameraConnection(String8(cameraId))) {
533+ ALOGW("Attempting to retrieve characteristics for system-only camera id %s, rejected",
534+ String8(cameraId).string());
535+ return STATUS_ERROR_FMT(ERROR_DISCONNECTED,
536+ "No camera device with ID \"%s\" currently available",
537+ String8(cameraId).string());
538+
539+ }
521540
541+ Status ret{};
522542 status_t res = mCameraProviderManager->getCameraCharacteristics(
523543 String8(cameraId).string(), cameraInfo);
524544 if (res != OK) {
@@ -1333,7 +1353,7 @@ bool CameraService::shouldRejectHiddenCameraConnection(const String8 & cameraId)
13331353 // publically hidden, we should reject the connection.
13341354 if (!hardware::IPCThreadState::self()->isServingCall() &&
13351355 CameraThreadState::getCallingPid() != getpid() &&
1336- mCameraProviderManager->isPublicallyHiddenSecureCamera(cameraId.c_str())) {
1356+ isPublicallyHiddenSecureCamera(cameraId)) {
13371357 return true;
13381358 }
13391359 return false;
@@ -1807,16 +1827,25 @@ Status CameraService::addListenerHelper(const sp<ICameraServiceListener>& listen
18071827 {
18081828 Mutex::Autolock lock(mCameraStatesLock);
18091829 for (auto& i : mCameraStates) {
1810- if (!isVendorListener &&
1811- mCameraProviderManager->isPublicallyHiddenSecureCamera(i.first.c_str())) {
1812- ALOGV("Cannot add public listener for hidden system-only %s for pid %d",
1813- i.first.c_str(), CameraThreadState::getCallingPid());
1814- continue;
1815- }
18161830 cameraStatuses->emplace_back(i.first, mapToInterface(i.second->getStatus()));
18171831 }
18181832 }
18191833
1834+ // Remove the camera statuses that should be hidden from the client, we do
1835+ // this after collecting the states in order to avoid holding
1836+ // mCameraStatesLock and mInterfaceLock (held in
1837+ // isPublicallyHiddenSecureCamera()) at the same time.
1838+ cameraStatuses->erase(std::remove_if(cameraStatuses->begin(), cameraStatuses->end(),
1839+ [this, &isVendorListener](const hardware::CameraStatus& s) {
1840+ bool ret = !isVendorListener && isPublicallyHiddenSecureCamera(s.cameraId);
1841+ if (ret) {
1842+ ALOGV("Cannot add public listener for hidden system-only %s for pid %d",
1843+ s.cameraId.c_str(), CameraThreadState::getCallingPid());
1844+ }
1845+ return ret;
1846+ }),
1847+ cameraStatuses->end());
1848+
18201849 /*
18211850 * Immediately signal current torch status to this listener only
18221851 * This may be a subset of all the devices, so don't include it in the response directly
@@ -2876,8 +2905,9 @@ void CameraService::SensorPrivacyPolicy::binderDied(const wp<IBinder>& /*who*/)
28762905 // ----------------------------------------------------------------------------
28772906
28782907 CameraService::CameraState::CameraState(const String8& id, int cost,
2879- const std::set<String8>& conflicting) : mId(id),
2880- mStatus(StatusInternal::NOT_PRESENT), mCost(cost), mConflicting(conflicting) {}
2908+ const std::set<String8>& conflicting, bool isHidden) : mId(id),
2909+ mStatus(StatusInternal::NOT_PRESENT), mCost(cost), mConflicting(conflicting),
2910+ mIsPublicallyHiddenSecureCamera(isHidden) {}
28812911
28822912 CameraService::CameraState::~CameraState() {}
28832913
@@ -2906,6 +2936,10 @@ String8 CameraService::CameraState::getId() const {
29062936 return mId;
29072937 }
29082938
2939+bool CameraService::CameraState::isPublicallyHiddenSecureCamera() const {
2940+ return mIsPublicallyHiddenSecureCamera;
2941+}
2942+
29092943 // ----------------------------------------------------------------------------
29102944 // ClientEventListener
29112945 // ----------------------------------------------------------------------------
@@ -3241,10 +3275,10 @@ void CameraService::updateStatus(StatusInternal status, const String8& cameraId,
32413275 cameraId.string());
32423276 return;
32433277 }
3244-
3278+ bool isHidden = isPublicallyHiddenSecureCamera(cameraId);
32453279 // Update the status for this camera state, then send the onStatusChangedCallbacks to each
32463280 // of the listeners with both the mStatusStatus and mStatusListenerLock held
3247- state->updateStatus(status, cameraId, rejectSourceStates, [this]
3281+ state->updateStatus(status, cameraId, rejectSourceStates, [this,&isHidden]
32483282 (const String8& cameraId, StatusInternal status) {
32493283
32503284 if (status != StatusInternal::ENUMERATING) {
@@ -3266,8 +3300,7 @@ void CameraService::updateStatus(StatusInternal status, const String8& cameraId,
32663300 Mutex::Autolock lock(mStatusListenerLock);
32673301
32683302 for (auto& listener : mListenerList) {
3269- if (!listener.first &&
3270- mCameraProviderManager->isPublicallyHiddenSecureCamera(cameraId.c_str())) {
3303+ if (!listener.first && isHidden) {
32713304 ALOGV("Skipping camera discovery callback for system-only camera %s",
32723305 cameraId.c_str());
32733306 continue;
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -470,7 +470,8 @@ private:
470470 * Make a new CameraState and set the ID, cost, and conflicting devices using the values
471471 * returned in the HAL's camera_info struct for each device.
472472 */
473- CameraState(const String8& id, int cost, const std::set<String8>& conflicting);
473+ CameraState(const String8& id, int cost, const std::set<String8>& conflicting,
474+ bool isHidden);
474475 virtual ~CameraState();
475476
476477 /**
@@ -522,6 +523,11 @@ private:
522523 */
523524 String8 getId() const;
524525
526+ /**
527+ * Return if the camera device is a publically hidden secure camera
528+ */
529+ bool isPublicallyHiddenSecureCamera() const;
530+
525531 private:
526532 const String8 mId;
527533 StatusInternal mStatus; // protected by mStatusLock
@@ -529,6 +535,7 @@ private:
529535 std::set<String8> mConflicting;
530536 mutable Mutex mStatusLock;
531537 CameraParameters mShimParams;
538+ const bool mIsPublicallyHiddenSecureCamera;
532539 }; // class CameraState
533540
534541 // Observer for UID lifecycle enforcing that UIDs in idle
@@ -633,7 +640,9 @@ private:
633640
634641 // Should an operation attempt on a cameraId be rejected, if the camera id is
635642 // advertised as a publically hidden secure camera, by the camera HAL ?
636- bool shouldRejectHiddenCameraConnection(const String8 & cameraId);
643+ bool shouldRejectHiddenCameraConnection(const String8& cameraId);
644+
645+ bool isPublicallyHiddenSecureCamera(const String8& cameraId);
637646
638647 // Single implementation shared between the various connect calls
639648 template<class CALLBACK, class CLIENT>
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -1063,19 +1063,35 @@ bool CameraProviderManager::isPublicallyHiddenSecureCamera(const std::string& id
10631063
10641064 bool CameraProviderManager::isPublicallyHiddenSecureCameraLocked(const std::string& id) const {
10651065 auto deviceInfo = findDeviceInfoLocked(id);
1066- if (deviceInfo == nullptr) {
1067- return false;
1066+ if (deviceInfo != nullptr) {
1067+ return deviceInfo->mIsPublicallyHiddenSecureCamera;
1068+ }
1069+ // If this is a hidden physical camera, we should return what kind of
1070+ // camera the enclosing logical camera is.
1071+ auto isHiddenAndParent = isHiddenPhysicalCameraInternal(id);
1072+ if (isHiddenAndParent.first) {
1073+ LOG_ALWAYS_FATAL_IF(id == isHiddenAndParent.second->mId,
1074+ "%s: hidden physical camera id %s and enclosing logical camera id %s are the same",
1075+ __FUNCTION__, id.c_str(), isHiddenAndParent.second->mId.c_str());
1076+ return isPublicallyHiddenSecureCameraLocked(isHiddenAndParent.second->mId);
10681077 }
1069- return deviceInfo->mIsPublicallyHiddenSecureCamera;
1078+ // Invalid camera id
1079+ return true;
10701080 }
10711081
1072-bool CameraProviderManager::isHiddenPhysicalCamera(const std::string& cameraId) {
1082+bool CameraProviderManager::isHiddenPhysicalCamera(const std::string& cameraId) const {
1083+ return isHiddenPhysicalCameraInternal(cameraId).first;
1084+}
1085+
1086+std::pair<bool, CameraProviderManager::ProviderInfo::DeviceInfo *>
1087+CameraProviderManager::isHiddenPhysicalCameraInternal(const std::string& cameraId) const {
1088+ auto falseRet = std::make_pair(false, nullptr);
10731089 for (auto& provider : mProviders) {
10741090 for (auto& deviceInfo : provider->mDevices) {
10751091 if (deviceInfo->mId == cameraId) {
10761092 // cameraId is found in public camera IDs advertised by the
10771093 // provider.
1078- return false;
1094+ return falseRet;
10791095 }
10801096 }
10811097 }
@@ -1087,7 +1103,7 @@ bool CameraProviderManager::isHiddenPhysicalCamera(const std::string& cameraId)
10871103 if (res != OK) {
10881104 ALOGE("%s: Failed to getCameraCharacteristics for id %s", __FUNCTION__,
10891105 deviceInfo->mId.c_str());
1090- return false;
1106+ return falseRet;
10911107 }
10921108
10931109 std::vector<std::string> physicalIds;
@@ -1099,16 +1115,16 @@ bool CameraProviderManager::isHiddenPhysicalCamera(const std::string& cameraId)
10991115 if (deviceVersion < CAMERA_DEVICE_API_VERSION_3_5) {
11001116 ALOGE("%s: Wrong deviceVersion %x for hiddenPhysicalCameraId %s",
11011117 __FUNCTION__, deviceVersion, cameraId.c_str());
1102- return false;
1118+ return falseRet;
11031119 } else {
1104- return true;
1120+ return std::make_pair(true, deviceInfo.get());
11051121 }
11061122 }
11071123 }
11081124 }
11091125 }
11101126
1111- return false;
1127+ return falseRet;
11121128 }
11131129
11141130 status_t CameraProviderManager::addProviderLocked(const std::string& newProvider) {
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -273,7 +273,7 @@ public:
273273 bool isLogicalCamera(const std::string& id, std::vector<std::string>* physicalCameraIds);
274274
275275 bool isPublicallyHiddenSecureCamera(const std::string& id) const;
276- bool isHiddenPhysicalCamera(const std::string& cameraId);
276+ bool isHiddenPhysicalCamera(const std::string& cameraId) const;
277277
278278 static const float kDepthARTolerance;
279279 private:
@@ -598,6 +598,11 @@ private:
598598 bool isPublicallyHiddenSecureCameraLocked(const std::string& id) const;
599599
600600 void filterLogicalCameraIdsLocked(std::vector<std::string>& deviceIds) const;
601+
602+ bool isPublicallyHiddenSecureCameraLocked(const std::string& id);
603+
604+ std::pair<bool, CameraProviderManager::ProviderInfo::DeviceInfo *>
605+ isHiddenPhysicalCameraInternal(const std::string& cameraId) const;
601606 };
602607
603608 } // namespace android