summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Kwangkyu Park <kk48.park@samsung.com> 2022-08-12 16:28:31 +0900
committer Kwangkyu Park <kk48.park@samsung.com> 2022-08-12 16:39:08 +0900
commiteb11b2401b2b964281c79c4615d174f32987e87c (patch)
tree8ce64e5887f1059c0ced45331caed036ccef624f
parent00545d0fd6ba561271b690bac51f3439d3bc56e5 (diff)
Fix an issue that the FoldStateListener induces a memory leak
FoldStateListener is non-static inner class and keeps reference to the outer class which is CameraManager. As CameraManager also keeps context with mContext, memory leak could exist. Changing FoldStateListener to static inner class, so that the class won't keep the reference. Bug: 242264787 Test: Manual test with memory profiling Change-Id: I77652bd94b50eabc80041e13274b619c0da36601
-rw-r--r--core/java/android/hardware/camera2/CameraManager.java44
1 files changed, 24 insertions, 20 deletions
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index b7c5644df107..a5a20627c176 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -124,9 +124,6 @@ public final class CameraManager {
private HandlerThread mHandlerThread;
private Handler mHandler;
private FoldStateListener mFoldStateListener;
- @GuardedBy("mLock")
- private ArrayList<WeakReference<DeviceStateListener>> mDeviceStateListeners = new ArrayList<>();
- private boolean mFoldedDeviceState;
/**
* @hide
@@ -135,31 +132,39 @@ public final class CameraManager {
void onDeviceStateChanged(boolean folded);
}
- private final class FoldStateListener implements DeviceStateManager.DeviceStateCallback {
+ private static final class FoldStateListener implements DeviceStateManager.DeviceStateCallback {
private final int[] mFoldedDeviceStates;
+ private ArrayList<WeakReference<DeviceStateListener>> mDeviceStateListeners =
+ new ArrayList<>();
+ private boolean mFoldedDeviceState;
+
public FoldStateListener(Context context) {
mFoldedDeviceStates = context.getResources().getIntArray(
com.android.internal.R.array.config_foldedDeviceStates);
}
- private void handleStateChange(int state) {
+ private synchronized void handleStateChange(int state) {
boolean folded = ArrayUtils.contains(mFoldedDeviceStates, state);
- synchronized (mLock) {
- mFoldedDeviceState = folded;
- ArrayList<WeakReference<DeviceStateListener>> invalidListeners = new ArrayList<>();
- for (WeakReference<DeviceStateListener> listener : mDeviceStateListeners) {
- DeviceStateListener callback = listener.get();
- if (callback != null) {
- callback.onDeviceStateChanged(folded);
- } else {
- invalidListeners.add(listener);
- }
- }
- if (!invalidListeners.isEmpty()) {
- mDeviceStateListeners.removeAll(invalidListeners);
+
+ mFoldedDeviceState = folded;
+ ArrayList<WeakReference<DeviceStateListener>> invalidListeners = new ArrayList<>();
+ for (WeakReference<DeviceStateListener> listener : mDeviceStateListeners) {
+ DeviceStateListener callback = listener.get();
+ if (callback != null) {
+ callback.onDeviceStateChanged(folded);
+ } else {
+ invalidListeners.add(listener);
}
}
+ if (!invalidListeners.isEmpty()) {
+ mDeviceStateListeners.removeAll(invalidListeners);
+ }
+ }
+
+ public synchronized void addDeviceStateListener(DeviceStateListener listener) {
+ listener.onDeviceStateChanged(mFoldedDeviceState);
+ mDeviceStateListeners.add(new WeakReference<>(listener));
}
@Override
@@ -183,9 +188,8 @@ public final class CameraManager {
public void registerDeviceStateListener(@NonNull CameraCharacteristics chars) {
synchronized (mLock) {
DeviceStateListener listener = chars.getDeviceStateListener();
- listener.onDeviceStateChanged(mFoldedDeviceState);
if (mFoldStateListener != null) {
- mDeviceStateListeners.add(new WeakReference<>(listener));
+ mFoldStateListener.addDeviceStateListener(listener);
}
}
}