Fix deadlock in CameraAccessController

Use separate lock for mObserverCount and to ensure the listener
is only registered once.

This breaks the resource allocation cycle and prevents deadlock
described in b/265618228.

Bug: 265618228
Test: atest VirtualDeviceManagerServiceTest CameraAccessControllerTest
Change-Id: Ifb8345319b367aa6492a46bea404658041272cc0
This commit is contained in:
Jan Sebechlebsky
2023-02-09 14:02:14 +01:00
parent c614b47a64
commit 674a47c38c

View File

@@ -45,6 +45,7 @@ class CameraAccessController extends CameraManager.AvailabilityCallback implemen
private static final String TAG = "CameraAccessController";
private final Object mLock = new Object();
private final Object mObserverLock = new Object();
private final Context mContext;
private final VirtualDeviceManagerInternal mVirtualDeviceManagerInternal;
@@ -53,7 +54,7 @@ class CameraAccessController extends CameraManager.AvailabilityCallback implemen
private final PackageManager mPackageManager;
private final UserManager mUserManager;
@GuardedBy("mLock")
@GuardedBy("mObserverLock")
private int mObserverCount = 0;
@GuardedBy("mLock")
@@ -107,7 +108,7 @@ class CameraAccessController extends CameraManager.AvailabilityCallback implemen
* Returns the number of observers currently relying on this controller.
*/
public int getObserverCount() {
synchronized (mLock) {
synchronized (mObserverLock) {
return mObserverCount;
}
}
@@ -117,7 +118,7 @@ class CameraAccessController extends CameraManager.AvailabilityCallback implemen
* already doing so.
*/
public void startObservingIfNeeded() {
synchronized (mLock) {
synchronized (mObserverLock) {
if (mObserverCount == 0) {
mCameraManager.registerAvailabilityCallback(mContext.getMainExecutor(), this);
}
@@ -129,7 +130,7 @@ class CameraAccessController extends CameraManager.AvailabilityCallback implemen
* Stop watching for camera access.
*/
public void stopObservingIfNeeded() {
synchronized (mLock) {
synchronized (mObserverLock) {
mObserverCount--;
if (mObserverCount <= 0) {
close();
@@ -169,7 +170,7 @@ class CameraAccessController extends CameraManager.AvailabilityCallback implemen
@Override
public void close() {
synchronized (mLock) {
synchronized (mObserverLock) {
if (mObserverCount < 0) {
Slog.wtf(TAG, "Unexpected negative mObserverCount: " + mObserverCount);
} else if (mObserverCount > 0) {