From 011754203cc1b68c9ec76ff82500be9830b56eb4 Mon Sep 17 00:00:00 2001 From: Mattia Iavarone Date: Tue, 31 Oct 2017 14:05:25 +0100 Subject: [PATCH] Avoid ConcurrentModificationExceptions in listeners (#88) --- .../cameraview/CameraViewTest.java | 19 +++++++++++++++++++ .../otaliastudios/cameraview/CameraView.java | 5 +++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java index 3f274413..8afa085c 100644 --- a/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java +++ b/cameraview/src/androidTest/java/com/otaliastudios/cameraview/CameraViewTest.java @@ -382,6 +382,7 @@ public class CameraViewTest extends BaseTest { //region testLocation + @SuppressWarnings("ConstantConditions") @Test public void testSetLocation() { cameraView.setLocation(50d, -50d); @@ -554,6 +555,7 @@ public class CameraViewTest extends BaseTest { //region Lists of listeners and processors + @SuppressWarnings("UseBulkOperation") @Test public void testCameraListenerList() { assertTrue(cameraView.mListeners.isEmpty()); @@ -571,8 +573,17 @@ public class CameraViewTest extends BaseTest { cameraView.clearCameraListeners(); assertTrue(cameraView.mListeners.isEmpty()); + + // Ensure this does not throw a ConcurrentModificationException + cameraView.addCameraListener(new CameraListener() {}); + cameraView.addCameraListener(new CameraListener() {}); + cameraView.addCameraListener(new CameraListener() {}); + for (CameraListener test : cameraView.mListeners) { + cameraView.mListeners.remove(test); + } } + @SuppressWarnings({"NullableProblems", "UseBulkOperation"}) @Test public void testFrameProcessorsList() { assertTrue(cameraView.mFrameProcessors.isEmpty()); @@ -592,6 +603,14 @@ public class CameraViewTest extends BaseTest { cameraView.clearFrameProcessors(); assertTrue(cameraView.mFrameProcessors.isEmpty()); + + // Ensure this does not throw a ConcurrentModificationException + cameraView.addFrameProcessor(new FrameProcessor() { public void process(Frame f) {} }); + cameraView.addFrameProcessor(new FrameProcessor() { public void process(Frame f) {} }); + cameraView.addFrameProcessor(new FrameProcessor() { public void process(Frame f) {} }); + for (FrameProcessor test : cameraView.mFrameProcessors) { + cameraView.mFrameProcessors.remove(test); + } } //endregion diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java index 6c31364c..b685da20 100644 --- a/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/CameraView.java @@ -29,6 +29,7 @@ import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; import static android.view.View.MeasureSpec.AT_MOST; import static android.view.View.MeasureSpec.EXACTLY; @@ -62,8 +63,8 @@ public class CameraView extends FrameLayout { private OrientationHelper mOrientationHelper; private CameraController mCameraController; private MediaActionSound mSound; - /* for tests */ ArrayList mListeners = new ArrayList<>(2); - /* for tests */ ArrayList mFrameProcessors = new ArrayList<>(1); + /* for tests */ List mListeners = new CopyOnWriteArrayList<>(); + /* for tests */ List mFrameProcessors = new CopyOnWriteArrayList<>(); // Views GridLinesLayout mGridLinesLayout;