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

Commit b4e2a5bc authored by Michal Olech's avatar Michal Olech
Browse files

[CEC Configuration] Fix race condition with listeners

Bug: 178095692
Test: atest HdmiCecConfigTest --iterations 25
Change-Id: I5ac00d596fe3d4b5af5f69d2fbaac9cc38f99ca1
parent b695454d
Loading
Loading
Loading
Loading
+24 −14
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import android.provider.Settings.Global;
import android.util.ArrayMap;
import android.util.Slog;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.hdmi.cec.config.CecSettings;
import com.android.server.hdmi.cec.config.Setting;
@@ -95,6 +96,9 @@ public class HdmiCecConfig {
    @Nullable private final CecSettings mSystemConfig;
    @Nullable private final CecSettings mVendorOverride;

    private final Object mLock = new Object();

    @GuardedBy("mLock")
    private final ArrayMap<Setting, Set<SettingChangeListener>>
            mSettingChangeListeners = new ArrayMap<>();

@@ -389,6 +393,7 @@ public class HdmiCecConfig {
    }

    private void notifySettingChanged(@NonNull Setting setting) {
        synchronized (mLock) {
            Set<SettingChangeListener> listeners = mSettingChangeListeners.get(setting);
            if (listeners == null) {
                return;  // No listeners registered, do nothing.
@@ -397,6 +402,7 @@ public class HdmiCecConfig {
                listener.onChange(setting.getName());
            }
        }
    }

    /**
     * This method registers Global Setting change observer.
@@ -440,11 +446,13 @@ public class HdmiCecConfig {
            throw new IllegalArgumentException("Change listeners for setting '" + name
                    + "' not supported.");
        }
        synchronized (mLock) {
            if (!mSettingChangeListeners.containsKey(setting)) {
                mSettingChangeListeners.put(setting, new HashSet<>());
            }
            mSettingChangeListeners.get(setting).add(listener);
        }
    }

    /**
     * Remove change listener for a given setting name.
@@ -455,6 +463,7 @@ public class HdmiCecConfig {
        if (setting == null) {
            throw new IllegalArgumentException("Setting '" + name + "' does not exist.");
        }
        synchronized (mLock) {
            if (mSettingChangeListeners.containsKey(setting)) {
                Set<SettingChangeListener> listeners = mSettingChangeListeners.get(setting);
                listeners.remove(listener);
@@ -463,6 +472,7 @@ public class HdmiCecConfig {
                }
            }
        }
    }

    /**
     * Returns a list of all settings based on the XML metadata.