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

Commit 515e89f9 authored by Emilian Peev's avatar Emilian Peev
Browse files

Camera: Use a single handler thread for device state callbacks

Use a single handler thread within the same camera client process
for processing device state changes.
This should avoid cases where clients continuously instantiate and
cache CameraManager instances until the process FD limit is reached.

Bug: 270551856
Test: atest -c -d
cts/tests/tests/virtualdevice/src/android/virtualdevice/cts/VirtualDeviceManagerBasicTest.java#getVirtualDevices_returnsAllVirtualDevices
--iterations=10
and ensure that the handler thread for device state callbacks remains
the same.

Change-Id: Ia659075947ab6c3f2bf56119b06f6397953dbd5a
parent 42dde263
Loading
Loading
Loading
Loading
+18 −9
Original line number Diff line number Diff line
@@ -142,24 +142,18 @@ public final class CameraManager {
                    PackageManager.PERMISSION_GRANTED;
        }

        mHandlerThread = new HandlerThread(TAG);
        mHandlerThread.start();
        mHandler = new Handler(mHandlerThread.getLooper());
        mFoldStateListener = new FoldStateListener(context);
        try {
            context.getSystemService(DeviceStateManager.class)
                    .registerCallback(new HandlerExecutor(mHandler), mFoldStateListener);
            context.getSystemService(DeviceStateManager.class).registerCallback(
                    new HandlerExecutor(CameraManagerGlobal.get().getDeviceStateHandler()),
                    mFoldStateListener);
        } catch (IllegalStateException e) {
            Log.v(TAG, "Failed to register device state listener!");
            Log.v(TAG, "Device state dependent characteristics updates will not be functional!");
            mHandlerThread.quitSafely();
            mHandler = null;
            mFoldStateListener = null;
        }
    }

    private HandlerThread mHandlerThread;
    private Handler mHandler;
    private FoldStateListener mFoldStateListener;

    /**
@@ -1645,6 +1639,9 @@ public final class CameraManager {
        private ICameraService mCameraService;
        private boolean mHasOpenCloseListenerPermission = false;

        private HandlerThread mDeviceStateHandlerThread;
        private Handler mDeviceStateHandler;

        // Singleton, don't allow construction
        private CameraManagerGlobal() { }

@@ -1658,6 +1655,18 @@ public final class CameraManager {
            return gCameraManager;
        }

        public Handler getDeviceStateHandler() {
            synchronized(mLock) {
                if (mDeviceStateHandlerThread == null) {
                    mDeviceStateHandlerThread = new HandlerThread(TAG);
                    mDeviceStateHandlerThread.start();
                    mDeviceStateHandler = new Handler(mDeviceStateHandlerThread.getLooper());
                }

                return mDeviceStateHandler;
            }
        }

        @Override
        public IBinder asBinder() {
            return this;