[SettingsProvider] fix byte count

Memory usage per package was limited by "bytes" but counted by
"character length". Every character is 2 bytes in Java. This CL fixes
the counting and also doubles the bytes limit so that it doesn't cause
any behavior changes.

BUG: 253499273
Test: atest com.android.providers.settings.SettingsStateTest
Change-Id: I7a8be794582c153adf43ec735d2563695ea1533d
This commit is contained in:
Songchun Fan
2022-10-13 14:23:16 -07:00
parent 783bcba343
commit e51a174c98
2 changed files with 22 additions and 20 deletions

View File

@@ -98,7 +98,7 @@ final class SettingsState {
private static final long MAX_WRITE_SETTINGS_DELAY_MILLIS = 2000;
public static final int MAX_BYTES_PER_APP_PACKAGE_UNLIMITED = -1;
public static final int MAX_BYTES_PER_APP_PACKAGE_LIMITED = 20000;
public static final int MAX_BYTES_PER_APP_PACKAGE_LIMITED = 40000;
public static final int VERSION_UNDEFINED = -1;
@@ -732,19 +732,19 @@ final class SettingsState {
}
@GuardedBy("mLock")
private int getNewMemoryUsagePerPackageLocked(String packageName, int deltaKeySize,
private int getNewMemoryUsagePerPackageLocked(String packageName, int deltaKeyLength,
String oldValue, String newValue, String oldDefaultValue, String newDefaultValue) {
if (isExemptFromMemoryUsageCap(packageName)) {
return 0;
}
final Integer currentSize = mPackageToMemoryUsage.get(packageName);
final int oldValueSize = (oldValue != null) ? oldValue.length() : 0;
final int newValueSize = (newValue != null) ? newValue.length() : 0;
final int oldDefaultValueSize = (oldDefaultValue != null) ? oldDefaultValue.length() : 0;
final int newDefaultValueSize = (newDefaultValue != null) ? newDefaultValue.length() : 0;
final int deltaSize = deltaKeySize + newValueSize + newDefaultValueSize
- oldValueSize - oldDefaultValueSize;
return Math.max((currentSize != null) ? currentSize + deltaSize : deltaSize, 0);
final int currentSize = mPackageToMemoryUsage.getOrDefault(packageName, 0);
final int oldValueLength = (oldValue != null) ? oldValue.length() : 0;
final int newValueLength = (newValue != null) ? newValue.length() : 0;
final int oldDefaultValueLength = (oldDefaultValue != null) ? oldDefaultValue.length() : 0;
final int newDefaultValueLength = (newDefaultValue != null) ? newDefaultValue.length() : 0;
final int deltaSize = (deltaKeyLength + newValueLength + newDefaultValueLength
- oldValueLength - oldDefaultValueLength) * Character.BYTES;
return Math.max(currentSize + deltaSize, 0);
}
@GuardedBy("mLock")

View File

@@ -329,46 +329,47 @@ public class SettingsStateTest extends AndroidTestCase {
final String testKey1 = SETTING_NAME;
final String testValue1 = Strings.repeat("A", 100);
settingsState.insertSettingLocked(testKey1, testValue1, null, true, TEST_PACKAGE);
int expectedMemUsage = testKey1.length() + testValue1.length()
+ testValue1.length() /* size for default */;
int expectedMemUsage = (testKey1.length() + testValue1.length()
+ testValue1.length() /* size for default */) * Character.BYTES;
assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
// Test inserting another key
final String testKey2 = SETTING_NAME + "2";
settingsState.insertSettingLocked(testKey2, testValue1, null, false, TEST_PACKAGE);
expectedMemUsage += testKey2.length() + testValue1.length();
expectedMemUsage += (testKey2.length() + testValue1.length()) * Character.BYTES;
assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
// Test updating first key with new default
final String testValue2 = Strings.repeat("A", 300);
settingsState.insertSettingLocked(testKey1, testValue2, null, true, TEST_PACKAGE);
expectedMemUsage += (testValue2.length() - testValue1.length()) * 2;
expectedMemUsage += (testValue2.length() - testValue1.length()) * 2 * Character.BYTES;
assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
// Test updating first key without new default
final String testValue3 = Strings.repeat("A", 50);
settingsState.insertSettingLocked(testKey1, testValue3, null, false, TEST_PACKAGE);
expectedMemUsage -= testValue2.length() - testValue3.length();
expectedMemUsage -= (testValue2.length() - testValue3.length()) * Character.BYTES;
assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
// Test updating second key
settingsState.insertSettingLocked(testKey2, testValue2, null, false, TEST_PACKAGE);
expectedMemUsage -= testValue1.length() - testValue2.length();
expectedMemUsage -= (testValue1.length() - testValue2.length()) * Character.BYTES;
assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
// Test resetting key
settingsState.resetSettingLocked(testKey1);
expectedMemUsage += testValue2.length() - testValue3.length();
expectedMemUsage += (testValue2.length() - testValue3.length()) * Character.BYTES;
assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
// Test resetting default value
settingsState.resetSettingDefaultValueLocked(testKey1);
expectedMemUsage -= testValue2.length();
expectedMemUsage -= testValue2.length() * Character.BYTES;
assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
// Test deletion
settingsState.deleteSettingLocked(testKey2);
expectedMemUsage -= testValue2.length() + testKey2.length() /* key is deleted too */;
expectedMemUsage -= (testValue2.length() + testKey2.length() /* key is deleted too */)
* Character.BYTES;
assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
// Test another package with a different key
@@ -376,7 +377,8 @@ public class SettingsStateTest extends AndroidTestCase {
final String testKey3 = SETTING_NAME + "3";
settingsState.insertSettingLocked(testKey3, testValue1, null, true, testPackage2);
assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE));
final int expectedMemUsage2 = testKey3.length() + testValue1.length() * 2;
final int expectedMemUsage2 = (testKey3.length() + testValue1.length() * 2)
* Character.BYTES;
assertEquals(expectedMemUsage2, settingsState.getMemoryUsage(testPackage2));
// Test system package