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

Commit a25fc68d authored by Nicolo' Mazzucato's avatar Nicolo' Mazzucato
Browse files

Fix concurrentModificationException of DevicePostureController listeners

Some listener ended up registering or unregistering other listeners while posture updates were sent. I coulnd't repro it, but we had a few reports from the field. I suspect there is a chain of calls that leads to the destruction of some objects (onDestroy) and triggers the postureController.removeListener, but only rarely.

Fix: 345390663
Test: DevicePostureControllerImplTest
Flag: NONE safe fix for rare and not reproducible exception
Change-Id: I00b5813267e917c65ca269324a9f17783069fd82
parent 2a2e0d1b
Loading
Loading
Loading
Loading
+8 −2
Original line number Diff line number Diff line
@@ -31,8 +31,8 @@ import com.android.systemui.util.Assert;

import kotlin.Unit;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Executor;

import javax.inject.Inject;
@@ -42,7 +42,13 @@ import javax.inject.Inject;
public class DevicePostureControllerImpl implements DevicePostureController {
    /** From androidx.window.common.COMMON_STATE_USE_BASE_STATE */
    private static final int COMMON_STATE_USE_BASE_STATE = 1000;
    private final List<Callback> mListeners = new ArrayList<>();
    /**
     * Despite this is always used only from the main thread, it might be that some listener
     * unregisters itself while we're sending the update, ending up modifying this while we're
     * iterating it.
     * Keeping a threadsafe list of listeners helps preventing ConcurrentModificationExceptions.
     */
    private final List<Callback> mListeners = new CopyOnWriteArrayList<>();
    private final List<DeviceState> mSupportedStates;
    private DeviceState mCurrentDeviceState;
    private int mCurrentDevicePosture = DEVICE_POSTURE_UNKNOWN;