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

Commit 7735c14b authored by Shai Barack's avatar Shai Barack
Browse files

Reduce memory usage of settings

Intern settings strings.
Store numeric IDs as a numeric type, not as a string.

Bug: 368681975
Change-Id: Id0b9582333aa170f0b5af5e88501473bae1971bf
Flag: EXEMPT bugfix
Test: CTS, CrystalBall, ART benchmark
parent 44ef2fbc
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -967,7 +967,7 @@ public class SettingsProvider extends ContentProvider {
        for (int i = 0; i < nameCount; i++) {
            String name = names.get(i);
            Setting setting = settingsState.getSettingLocked(name);
            pw.print("_id:"); pw.print(toDumpString(setting.getId()));
            pw.print("_id:"); pw.print(toDumpString(String.valueOf(setting.getId())));
            pw.print(" name:"); pw.print(toDumpString(name));
            if (setting.getPackageName() != null) {
                pw.print(" pkg:"); pw.print(setting.getPackageName());
@@ -2785,7 +2785,7 @@ public class SettingsProvider extends ContentProvider {

            switch (column) {
                case Settings.NameValueTable._ID -> {
                    values[i] = setting.getId();
                    values[i] = String.valueOf(setting.getId());
                }
                case Settings.NameValueTable.NAME -> {
                    values[i] = setting.getName();
+45 −22
Original line number Diff line number Diff line
@@ -1363,7 +1363,10 @@ final class SettingsState {
                    }

                    try {
                        if (writeSingleSetting(mVersion, serializer, setting.getId(),
                        if (writeSingleSetting(
                                mVersion,
                                serializer,
                                Long.toString(setting.getId()),
                                setting.getName(),
                                setting.getValue(), setting.getDefaultValue(),
                                setting.getPackageName(),
@@ -1632,7 +1635,7 @@ final class SettingsState {
            TypedXmlPullParser parser = Xml.resolvePullParser(in);
            parseStateLocked(parser);
            return true;
        } catch (XmlPullParserException | IOException e) {
        } catch (XmlPullParserException | IOException | NumberFormatException e) {
            Slog.e(LOG_TAG, "parse settings xml failed", e);
            return false;
        } finally {
@@ -1652,7 +1655,7 @@ final class SettingsState {
    }

    private void parseStateLocked(TypedXmlPullParser parser)
            throws IOException, XmlPullParserException {
            throws IOException, XmlPullParserException, NumberFormatException {
        final int outerDepth = parser.getDepth();
        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
@@ -1708,7 +1711,7 @@ final class SettingsState {

    @GuardedBy("mLock")
    private void parseSettingsLocked(TypedXmlPullParser parser)
            throws IOException, XmlPullParserException {
            throws IOException, XmlPullParserException, NumberFormatException {

        mVersion = parser.getAttributeInt(null, ATTR_VERSION);

@@ -1776,7 +1779,7 @@ final class SettingsState {
                    }
                }
                mSettings.put(name, new Setting(name, value, defaultValue, packageName, tag,
                        fromSystem, id, isPreservedInRestore));
                        fromSystem, Long.valueOf(id), isPreservedInRestore));

                if (DEBUG_PERSISTENCE) {
                    Slog.i(LOG_TAG, "[RESTORED] " + name + "=" + value);
@@ -1866,7 +1869,7 @@ final class SettingsState {
        private String value;
        private String defaultValue;
        private String packageName;
        private String id;
        private long id;
        private String tag;
        // Whether the default is set by the system
        private boolean defaultFromSystem;
@@ -1898,30 +1901,27 @@ final class SettingsState {
        }

        public Setting(String name, String value, String defaultValue,
                String packageName, String tag, boolean fromSystem, String id) {
                String packageName, String tag, boolean fromSystem, long id) {
            this(name, value, defaultValue, packageName, tag, fromSystem, id,
                    /* isOverrideableByRestore */ false);
        }

        Setting(String name, String value, String defaultValue,
                String packageName, String tag, boolean fromSystem, String id,
                String packageName, String tag, boolean fromSystem, long id,
                boolean isValuePreservedInRestore) {
            mNextId = Math.max(mNextId, Long.parseLong(id) + 1);
            if (NULL_VALUE.equals(value)) {
                value = null;
            }
            mNextId = Math.max(mNextId, id + 1);
            init(name, value, tag, defaultValue, packageName, fromSystem, id,
                    isValuePreservedInRestore);
        }

        private void init(String name, String value, String tag, String defaultValue,
                String packageName, boolean fromSystem, String id,
                String packageName, boolean fromSystem, long id,
                boolean isValuePreservedInRestore) {
            this.name = name;
            this.value = value;
            this.value = internValue(value);
            this.tag = tag;
            this.defaultValue = defaultValue;
            this.packageName = packageName;
            this.defaultValue = internValue(defaultValue);
            this.packageName = TextUtils.safeIntern(packageName);
            this.id = id;
            this.defaultFromSystem = fromSystem;
            this.isValuePreservedInRestore = isValuePreservedInRestore;
@@ -1959,7 +1959,7 @@ final class SettingsState {
            return isValuePreservedInRestore;
        }

        public String getId() {
        public long getId() {
            return id;
        }

@@ -1992,9 +1992,6 @@ final class SettingsState {
        private boolean update(String value, boolean setDefault, String packageName, String tag,
                boolean forceNonSystemPackage, boolean overrideableByRestore,
                boolean resetToDefault) {
            if (NULL_VALUE.equals(value)) {
                value = null;
            }
            final boolean callerSystem = !forceNonSystemPackage &&
                    !isNull() && (isCalledFromSystem(packageName)
                    || isSystemPackage(mContext, packageName));
@@ -2039,7 +2036,7 @@ final class SettingsState {
            }

            init(name, value, tag, defaultValue, packageName, defaultFromSystem,
                    String.valueOf(mNextId++), isPreserved);
                    mNextId++, isPreserved);

            return true;
        }
@@ -2051,6 +2048,32 @@ final class SettingsState {
                    + " defaultFromSystem=" + defaultFromSystem + "}";
        }

        /**
         * Interns a string if it's a common setting value.
         * Otherwise returns the given string.
         */
        static String internValue(String str) {
            if (str == null) {
                return null;
            }
            switch (str) {
                case "true":
                    return "true";
                case "false":
                    return "false";
                case "0":
                    return "0";
                case "1":
                    return "1";
                case "":
                    return "";
                case "null":
                    return null;  // explicit null has special handling
                default:
                    return str;
            }
        }

        private boolean shouldPreserveSetting(boolean overrideableByRestore,
                boolean resetToDefault, String packageName, String value) {
            if (resetToDefault) {