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

Commit 6021c546 authored by Song Chun Fan's avatar Song Chun Fan Committed by Android (Google) Code Review
Browse files

Merge "[SettingsProvider] fix memory usage counting when owning packages change" into main

parents cb1aa699 25b7e158
Loading
Loading
Loading
Loading
+26 −5
Original line number Diff line number Diff line
@@ -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;

@@ -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();

+49 −4
Original line number Diff line number Diff line
@@ -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));

@@ -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 {
@@ -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
@@ -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));
    }
}