diff options
4 files changed, 41 insertions, 11 deletions
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java index 7cec99d4189f..8f459c647316 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java @@ -95,7 +95,9 @@ final class SettingsState { static final int SETTINGS_VERSION_NEW_ENCODING = 121; + // LINT.IfChange public static final int MAX_LENGTH_PER_STRING = 32768; + // LINT.ThenChange(/services/core/java/com/android/server/audio/AudioDeviceInventory.java:settings_max_length_per_string) private static final long WRITE_SETTINGS_DELAY_MILLIS = 200; private static final long MAX_WRITE_SETTINGS_DELAY_MILLIS = 2000; diff --git a/services/core/java/com/android/server/audio/AdiDeviceState.java b/services/core/java/com/android/server/audio/AdiDeviceState.java index ffdab7dfbfa4..9ae43a03515a 100644 --- a/services/core/java/com/android/server/audio/AdiDeviceState.java +++ b/services/core/java/com/android/server/audio/AdiDeviceState.java @@ -235,9 +235,10 @@ public final class AdiDeviceState { * {@link AdiDeviceState#toPersistableString()}. */ public static int getPeristedMaxSize() { - return 36; /* (mDeviceType)2 + (mDeviceAddress)17 + (mInternalDeviceType)9 + (mSAEnabled)1 + return 39; /* (mDeviceType)2 + (mDeviceAddress)17 + (mInternalDeviceType)9 + (mSAEnabled)1 + (mHasHeadTracker)1 + (mHasHeadTrackerEnabled)1 - + (SETTINGS_FIELD_SEPARATOR)5 */ + + (mAudioDeviceCategory)1 + (SETTINGS_FIELD_SEPARATOR)6 + + (SETTING_DEVICE_SEPARATOR)1 */ } @Nullable diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java index 9cf15184027b..80917533cce1 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java +++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java @@ -2686,11 +2686,15 @@ public class AudioDeviceBroker { return; } final SettingsAdapter settingsAdapter = mAudioService.getSettings(); - boolean res = settingsAdapter.putSecureStringForUser(mAudioService.getContentResolver(), - Settings.Secure.AUDIO_DEVICE_INVENTORY, - deviceSettings, UserHandle.USER_CURRENT); - if (!res) { - Log.e(TAG, "error saving AdiDeviceState: " + deviceSettings); + try { + boolean res = settingsAdapter.putSecureStringForUser(mAudioService.getContentResolver(), + Settings.Secure.AUDIO_DEVICE_INVENTORY, + deviceSettings, UserHandle.USER_CURRENT); + if (!res) { + Log.e(TAG, "error saving AdiDeviceState: " + deviceSettings); + } + } catch (IllegalArgumentException e) { + Log.e(TAG, "error saving AdiDeviceState: " + deviceSettings, e); } } diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java index d077ebc9c86c..34cfdfaa7974 100644 --- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java +++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java @@ -30,7 +30,6 @@ import static android.media.AudioSystem.isBluetoothOutDevice; import static android.media.AudioSystem.isBluetoothScoOutDevice; import static android.media.audio.Flags.automaticBtDeviceType; - import static com.android.internal.annotations.VisibleForTesting.Visibility.PACKAGE; import android.annotation.NonNull; @@ -81,7 +80,6 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; @@ -104,6 +102,14 @@ public class AudioDeviceInventory { private static final String SETTING_DEVICE_SEPARATOR_CHAR = "|"; private static final String SETTING_DEVICE_SEPARATOR = "\\|"; + /** Max String length that can be persisted within the Settings. */ + // LINT.IfChange(settings_max_length_per_string) + private static final int MAX_SETTINGS_LENGTH_PER_STRING = 32768; + // LINT.ThenChange(/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java) + + private static final int MAX_DEVICE_INVENTORY_ENTRIES = + MAX_SETTINGS_LENGTH_PER_STRING / AdiDeviceState.getPeristedMaxSize(); + // lock to synchronize all access to mConnectedDevices and mApmConnectedDevices private final Object mDevicesLock = new Object(); @@ -113,7 +119,8 @@ public class AudioDeviceInventory { private final Object mDeviceInventoryLock = new Object(); @GuardedBy("mDeviceInventoryLock") - private final HashMap<Pair<Integer, String>, AdiDeviceState> mDeviceInventory = new HashMap<>(); + private final LinkedHashMap<Pair<Integer, String>, AdiDeviceState> mDeviceInventory = + new LinkedHashMap<>(); Collection<AdiDeviceState> getImmutableDeviceInventory() { final List<AdiDeviceState> newList; @@ -136,6 +143,7 @@ public class AudioDeviceInventory { oldState.setSAEnabled(newState.isSAEnabled()); return oldState; }); + checkDeviceInventorySize_l(); } mDeviceBroker.postSynchronizeAdiDevicesInInventory(deviceState); } @@ -173,6 +181,8 @@ public class AudioDeviceInventory { ads.setAudioDeviceCategory(category); mDeviceInventory.put(ads.getDeviceId(), ads); + checkDeviceInventorySize_l(); + mDeviceBroker.postUpdatedAdiDeviceState(ads); mDeviceBroker.postPersistAudioDeviceSettings(); } @@ -200,6 +210,7 @@ public class AudioDeviceInventory { } return oldState; }); + checkDeviceInventorySize_l(); } if (updatedCategory.get()) { mDeviceBroker.postUpdatedAdiDeviceState(deviceState); @@ -272,6 +283,18 @@ public class AudioDeviceInventory { } } + @GuardedBy("mDeviceInventoryLock") + private void checkDeviceInventorySize_l() { + if (mDeviceInventory.size() > MAX_DEVICE_INVENTORY_ENTRIES) { + // remove the first element + Iterator<Entry<Pair<Integer, String>, AdiDeviceState>> iterator = + mDeviceInventory.entrySet().iterator(); + if (iterator.hasNext()) { + iterator.remove(); + } + } + } + @GuardedBy({"mDevicesLock", "mDeviceInventoryLock"}) private boolean synchronizeBleDeviceInInventory(AdiDeviceState updatedDevice) { for (DeviceInfo di : mConnectedDevices.values()) { @@ -2806,7 +2829,7 @@ public class AudioDeviceInventory { deviceCatalogSize = mDeviceInventory.size(); final StringBuilder settingsBuilder = new StringBuilder( - deviceCatalogSize * AdiDeviceState.getPeristedMaxSize()); + deviceCatalogSize * AdiDeviceState.getPeristedMaxSize()); Iterator<AdiDeviceState> iterator = mDeviceInventory.values().iterator(); if (iterator.hasNext()) { |