From 515e89f909b17e5befdcac128614264172b899df Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Thu, 23 Feb 2023 12:30:12 -0800 Subject: [PATCH] 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 --- .../hardware/camera2/CameraManager.java | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java index 19719a88ab2e8..fbc018444dc5c 100644 --- a/core/java/android/hardware/camera2/CameraManager.java +++ b/core/java/android/hardware/camera2/CameraManager.java @@ -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;