[CEC Configuration] Fix race condition with listeners
Bug: 178095692 Test: atest HdmiCecConfigTest --iterations 25 Change-Id: I5ac00d596fe3d4b5af5f69d2fbaac9cc38f99ca1
This commit is contained in:
@@ -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,12 +393,14 @@ public class HdmiCecConfig {
|
||||
}
|
||||
|
||||
private void notifySettingChanged(@NonNull Setting setting) {
|
||||
Set<SettingChangeListener> listeners = mSettingChangeListeners.get(setting);
|
||||
if (listeners == null) {
|
||||
return; // No listeners registered, do nothing.
|
||||
}
|
||||
for (SettingChangeListener listener: listeners) {
|
||||
listener.onChange(setting.getName());
|
||||
synchronized (mLock) {
|
||||
Set<SettingChangeListener> listeners = mSettingChangeListeners.get(setting);
|
||||
if (listeners == null) {
|
||||
return; // No listeners registered, do nothing.
|
||||
}
|
||||
for (SettingChangeListener listener: listeners) {
|
||||
listener.onChange(setting.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,10 +446,12 @@ public class HdmiCecConfig {
|
||||
throw new IllegalArgumentException("Change listeners for setting '" + name
|
||||
+ "' not supported.");
|
||||
}
|
||||
if (!mSettingChangeListeners.containsKey(setting)) {
|
||||
mSettingChangeListeners.put(setting, new HashSet<>());
|
||||
synchronized (mLock) {
|
||||
if (!mSettingChangeListeners.containsKey(setting)) {
|
||||
mSettingChangeListeners.put(setting, new HashSet<>());
|
||||
}
|
||||
mSettingChangeListeners.get(setting).add(listener);
|
||||
}
|
||||
mSettingChangeListeners.get(setting).add(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -455,11 +463,13 @@ public class HdmiCecConfig {
|
||||
if (setting == null) {
|
||||
throw new IllegalArgumentException("Setting '" + name + "' does not exist.");
|
||||
}
|
||||
if (mSettingChangeListeners.containsKey(setting)) {
|
||||
Set<SettingChangeListener> listeners = mSettingChangeListeners.get(setting);
|
||||
listeners.remove(listener);
|
||||
if (listeners.isEmpty()) {
|
||||
mSettingChangeListeners.remove(setting);
|
||||
synchronized (mLock) {
|
||||
if (mSettingChangeListeners.containsKey(setting)) {
|
||||
Set<SettingChangeListener> listeners = mSettingChangeListeners.get(setting);
|
||||
listeners.remove(listener);
|
||||
if (listeners.isEmpty()) {
|
||||
mSettingChangeListeners.remove(setting);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user