Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 674a47c3 authored by Jan Sebechlebsky's avatar Jan Sebechlebsky
Browse files

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
parent c614b47a
Loading
Loading
Loading
Loading
+6 −5
Original line number Diff line number Diff line
@@ -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) {