Loading packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java +26 −5 Original line number Diff line number Diff line Loading @@ -600,14 +600,25 @@ final class SettingsState { } Setting oldState = mSettings.get(name); String previousOwningPackage = (oldState != null) ? oldState.packageName : null; // If the old state doesn't exist, no need to handle the owning package change final boolean owningPackageChanged = previousOwningPackage != null && !previousOwningPackage.equals(packageName); String oldValue = (oldState != null) ? oldState.value : null; String oldDefaultValue = (oldState != null) ? oldState.defaultValue : null; String newDefaultValue = makeDefault ? value : oldDefaultValue; int newSize = getNewMemoryUsagePerPackageLocked(packageName, oldValue == null ? name.length() : 0 /* deltaKeySize */, oldValue, value, oldDefaultValue, newDefaultValue); checkNewMemoryUsagePerPackageLocked(packageName, newSize); int newSizeForCurrentPackage = getNewMemoryUsagePerPackageLocked(packageName, /* deltaKeyLength= */ (oldState == null || owningPackageChanged) ? name.length() : 0, /* oldValue= */ owningPackageChanged ? null : oldValue, /* newValue= */ value, /* oldDefaultValue= */ owningPackageChanged ? null : oldDefaultValue, /* newDefaultValue = */ newDefaultValue); // Only check the memory usage for the current package. Even if the owning package // has changed, the previous owning package will only have a reduced memory usage, so // there is no need to check its memory usage. checkNewMemoryUsagePerPackageLocked(packageName, newSizeForCurrentPackage); Setting newState; Loading @@ -629,7 +640,17 @@ final class SettingsState { addHistoricalOperationLocked(HISTORICAL_OPERATION_UPDATE, newState); updateMemoryUsagePerPackageLocked(packageName, newSize); updateMemoryUsagePerPackageLocked(packageName, newSizeForCurrentPackage); if (owningPackageChanged) { int newSizeForPreviousPackage = getNewMemoryUsagePerPackageLocked(previousOwningPackage, /* deltaKeyLength= */ -name.length(), /* oldValue= */ oldValue, /* newValue= */ null, /* oldDefaultValue= */ oldDefaultValue, /* newDefaultValue = */ null); updateMemoryUsagePerPackageLocked(previousOwningPackage, newSizeForPreviousPackage); } scheduleWriteIfNeededLocked(); Loading packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java +49 −4 Original line number Diff line number Diff line Loading @@ -585,9 +585,9 @@ public class SettingsStateTest { * Character.BYTES; assertEquals(expectedMemUsage2, settingsState.getMemoryUsage(testPackage2)); // Test system package // Let system package take over testKey1 which is no longer subject to memory usage counting settingsState.insertSettingLocked(testKey1, testValue1, null, true, SYSTEM_PACKAGE); assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE)); assertEquals(0, settingsState.getMemoryUsage(TEST_PACKAGE)); assertEquals(expectedMemUsage2, settingsState.getMemoryUsage(testPackage2)); assertEquals(0, settingsState.getMemoryUsage(SYSTEM_PACKAGE)); Loading @@ -599,7 +599,7 @@ public class SettingsStateTest { } catch (IllegalStateException ex) { assertTrue(ex.getMessage().contains("You are adding too many system settings")); } assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE)); assertEquals(0, settingsState.getMemoryUsage(TEST_PACKAGE)); // Test invalid key try { Loading @@ -609,7 +609,7 @@ public class SettingsStateTest { } catch (IllegalStateException ex) { assertTrue(ex.getMessage().contains("You are adding too many system settings")); } assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE)); assertEquals(0, settingsState.getMemoryUsage(TEST_PACKAGE)); } @Test Loading Loading @@ -902,4 +902,49 @@ public class SettingsStateTest { assertEquals("false", s.getValue()); } } @Test public void testMemoryUsagePerPackage_SameSettingUsedByDifferentPackages() { SettingsState settingsState = new SettingsState( InstrumentationRegistry.getContext(), mLock, mSettingsFile, 1, SettingsState.MAX_BYTES_PER_APP_PACKAGE_LIMITED, Looper.getMainLooper()); final String testKey1 = SETTING_NAME; final String testKey2 = SETTING_NAME + "_2"; final String testValue1 = Strings.repeat("A", 100); final String testValue2 = Strings.repeat("A", 50); final String package1 = "p1"; final String package2 = "p2"; settingsState.insertSettingLocked(testKey1, testValue1, null, false, package1); settingsState.insertSettingLocked(testKey2, testValue1, null, true, package2); // Package1's usage should be remain the same Package2 owns a different setting int expectedMemUsageForPackage1 = (testKey1.length() + testValue1.length()) * Character.BYTES; int expectedMemUsageForPackage2 = (testKey2.length() + testValue1.length() + testValue1.length() /* size for default */) * Character.BYTES; assertEquals(expectedMemUsageForPackage1, settingsState.getMemoryUsage(package1)); assertEquals(expectedMemUsageForPackage2, settingsState.getMemoryUsage(package2)); settingsState.insertSettingLocked(testKey1, testValue2, null, false, package2); // Package1's usage should be cleared because the setting is taken over by another package expectedMemUsageForPackage1 = 0; assertEquals(expectedMemUsageForPackage1, settingsState.getMemoryUsage(package1)); // Package2 now owns two settings expectedMemUsageForPackage2 = (testKey1.length() + testValue2.length() + testKey2.length() + testValue1.length() + testValue1.length() /* size for default */) * Character.BYTES; assertEquals(expectedMemUsageForPackage2, settingsState.getMemoryUsage(package2)); settingsState.insertSettingLocked(testKey1, testValue1, null, true, package1); // Package1 now owns setting1 expectedMemUsageForPackage1 = (testKey1.length() + testValue1.length() + testValue1.length() /* size for default */) * Character.BYTES; assertEquals(expectedMemUsageForPackage1, settingsState.getMemoryUsage(package1)); // Package2 now only own setting2 expectedMemUsageForPackage2 = (testKey2.length() + testValue1.length() + testValue1.length() /* size for default */) * Character.BYTES; assertEquals(expectedMemUsageForPackage2, settingsState.getMemoryUsage(package2)); } } Loading
packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java +26 −5 Original line number Diff line number Diff line Loading @@ -600,14 +600,25 @@ final class SettingsState { } Setting oldState = mSettings.get(name); String previousOwningPackage = (oldState != null) ? oldState.packageName : null; // If the old state doesn't exist, no need to handle the owning package change final boolean owningPackageChanged = previousOwningPackage != null && !previousOwningPackage.equals(packageName); String oldValue = (oldState != null) ? oldState.value : null; String oldDefaultValue = (oldState != null) ? oldState.defaultValue : null; String newDefaultValue = makeDefault ? value : oldDefaultValue; int newSize = getNewMemoryUsagePerPackageLocked(packageName, oldValue == null ? name.length() : 0 /* deltaKeySize */, oldValue, value, oldDefaultValue, newDefaultValue); checkNewMemoryUsagePerPackageLocked(packageName, newSize); int newSizeForCurrentPackage = getNewMemoryUsagePerPackageLocked(packageName, /* deltaKeyLength= */ (oldState == null || owningPackageChanged) ? name.length() : 0, /* oldValue= */ owningPackageChanged ? null : oldValue, /* newValue= */ value, /* oldDefaultValue= */ owningPackageChanged ? null : oldDefaultValue, /* newDefaultValue = */ newDefaultValue); // Only check the memory usage for the current package. Even if the owning package // has changed, the previous owning package will only have a reduced memory usage, so // there is no need to check its memory usage. checkNewMemoryUsagePerPackageLocked(packageName, newSizeForCurrentPackage); Setting newState; Loading @@ -629,7 +640,17 @@ final class SettingsState { addHistoricalOperationLocked(HISTORICAL_OPERATION_UPDATE, newState); updateMemoryUsagePerPackageLocked(packageName, newSize); updateMemoryUsagePerPackageLocked(packageName, newSizeForCurrentPackage); if (owningPackageChanged) { int newSizeForPreviousPackage = getNewMemoryUsagePerPackageLocked(previousOwningPackage, /* deltaKeyLength= */ -name.length(), /* oldValue= */ oldValue, /* newValue= */ null, /* oldDefaultValue= */ oldDefaultValue, /* newDefaultValue = */ null); updateMemoryUsagePerPackageLocked(previousOwningPackage, newSizeForPreviousPackage); } scheduleWriteIfNeededLocked(); Loading
packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java +49 −4 Original line number Diff line number Diff line Loading @@ -585,9 +585,9 @@ public class SettingsStateTest { * Character.BYTES; assertEquals(expectedMemUsage2, settingsState.getMemoryUsage(testPackage2)); // Test system package // Let system package take over testKey1 which is no longer subject to memory usage counting settingsState.insertSettingLocked(testKey1, testValue1, null, true, SYSTEM_PACKAGE); assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE)); assertEquals(0, settingsState.getMemoryUsage(TEST_PACKAGE)); assertEquals(expectedMemUsage2, settingsState.getMemoryUsage(testPackage2)); assertEquals(0, settingsState.getMemoryUsage(SYSTEM_PACKAGE)); Loading @@ -599,7 +599,7 @@ public class SettingsStateTest { } catch (IllegalStateException ex) { assertTrue(ex.getMessage().contains("You are adding too many system settings")); } assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE)); assertEquals(0, settingsState.getMemoryUsage(TEST_PACKAGE)); // Test invalid key try { Loading @@ -609,7 +609,7 @@ public class SettingsStateTest { } catch (IllegalStateException ex) { assertTrue(ex.getMessage().contains("You are adding too many system settings")); } assertEquals(expectedMemUsage, settingsState.getMemoryUsage(TEST_PACKAGE)); assertEquals(0, settingsState.getMemoryUsage(TEST_PACKAGE)); } @Test Loading Loading @@ -902,4 +902,49 @@ public class SettingsStateTest { assertEquals("false", s.getValue()); } } @Test public void testMemoryUsagePerPackage_SameSettingUsedByDifferentPackages() { SettingsState settingsState = new SettingsState( InstrumentationRegistry.getContext(), mLock, mSettingsFile, 1, SettingsState.MAX_BYTES_PER_APP_PACKAGE_LIMITED, Looper.getMainLooper()); final String testKey1 = SETTING_NAME; final String testKey2 = SETTING_NAME + "_2"; final String testValue1 = Strings.repeat("A", 100); final String testValue2 = Strings.repeat("A", 50); final String package1 = "p1"; final String package2 = "p2"; settingsState.insertSettingLocked(testKey1, testValue1, null, false, package1); settingsState.insertSettingLocked(testKey2, testValue1, null, true, package2); // Package1's usage should be remain the same Package2 owns a different setting int expectedMemUsageForPackage1 = (testKey1.length() + testValue1.length()) * Character.BYTES; int expectedMemUsageForPackage2 = (testKey2.length() + testValue1.length() + testValue1.length() /* size for default */) * Character.BYTES; assertEquals(expectedMemUsageForPackage1, settingsState.getMemoryUsage(package1)); assertEquals(expectedMemUsageForPackage2, settingsState.getMemoryUsage(package2)); settingsState.insertSettingLocked(testKey1, testValue2, null, false, package2); // Package1's usage should be cleared because the setting is taken over by another package expectedMemUsageForPackage1 = 0; assertEquals(expectedMemUsageForPackage1, settingsState.getMemoryUsage(package1)); // Package2 now owns two settings expectedMemUsageForPackage2 = (testKey1.length() + testValue2.length() + testKey2.length() + testValue1.length() + testValue1.length() /* size for default */) * Character.BYTES; assertEquals(expectedMemUsageForPackage2, settingsState.getMemoryUsage(package2)); settingsState.insertSettingLocked(testKey1, testValue1, null, true, package1); // Package1 now owns setting1 expectedMemUsageForPackage1 = (testKey1.length() + testValue1.length() + testValue1.length() /* size for default */) * Character.BYTES; assertEquals(expectedMemUsageForPackage1, settingsState.getMemoryUsage(package1)); // Package2 now only own setting2 expectedMemUsageForPackage2 = (testKey2.length() + testValue1.length() + testValue1.length() /* size for default */) * Character.BYTES; assertEquals(expectedMemUsageForPackage2, settingsState.getMemoryUsage(package2)); } }