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

Commit eabb3370 authored by Hongyi Zhang's avatar Hongyi Zhang Committed by Android (Google) Code Review
Browse files

Merge "SettingsToPropertiesMapper integrate with DeviceConfig API"

parents 7e838240 c4aad0e5
Loading
Loading
Loading
Loading
+26 −16
Original line number Diff line number Diff line
@@ -19,8 +19,10 @@ package com.android.server.am;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.SystemProperties;
import android.provider.DeviceConfig;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Slog;
@@ -61,13 +63,18 @@ class SettingsToPropertiesMapper {
    // Add the global setting you want to push to native level as experiment flag into this list.
    //
    // NOTE: please grant write permission system property prefix
    // with format persist.experiment.[experiment_category_name]. in system_server.te and grant read
    // permission in the corresponding .te file your feature belongs to.
    // with format persist.device_config.global_settings.[flag_name] in system_server.te and grant
    // read permission in the corresponding .te file your feature belongs to.
    @VisibleForTesting
    static final String[] sGlobalSettings = new String[] {
            Settings.Global.NATIVE_FLAGS_HEALTH_CHECK_ENABLED,
    };

    // All the flags under the listed DeviceConfig scopes will be synced to native level.
    //
    // NOTE: please grant write permission system property prefix
    // with format persist.device_config.[device_config_scope]. in system_server.te and grant read
    // permission in the corresponding .te file your feature belongs to.
    @VisibleForTesting
    static final String[] sDeviceConfigScopes = new String[] {
    };
@@ -104,19 +111,31 @@ class SettingsToPropertiesMapper {
            ContentObserver co = new ContentObserver(null) {
                @Override
                public void onChange(boolean selfChange) {
                    updatePropertyFromSetting(globalSetting, propName, true);
                    updatePropertyFromSetting(globalSetting, propName);
                }
            };

            // only updating on starting up when no native flags reset is performed during current
            // booting.
            if (!isNativeFlagsResetPerformed()) {
                updatePropertyFromSetting(globalSetting, propName, true);
                updatePropertyFromSetting(globalSetting, propName);
            }
            mContentResolver.registerContentObserver(settingUri, false, co);
        }

        // TODO: address sDeviceConfigScopes after DeviceConfig APIs are available.
        for (String deviceConfigScope : mDeviceConfigScopes) {
            DeviceConfig.addOnPropertyChangedListener(
                    deviceConfigScope,
                    AsyncTask.THREAD_POOL_EXECUTOR,
                    (String scope, String name, String value) -> {
                        String propertyName = makePropertyName(scope, name);
                        if (propertyName == null) {
                            log("unable to construct system property for " + scope + "/" + name);
                            return;
                        }
                        setProperty(propertyName, value);
                    });
        }
    }

    public static SettingsToPropertiesMapper start(ContentResolver contentResolver) {
@@ -184,15 +203,6 @@ class SettingsToPropertiesMapper {
        return propertyName;
    }

    private String getSetting(String name, boolean isGlobalSetting) {
        if (isGlobalSetting) {
            return Settings.Global.getString(mContentResolver, name);
        } else {
            // TODO: complete the code after DeviceConfig APIs implemented.
            return null;
        }
    }

    private void setProperty(String key, String value) {
        // Check if need to clear the property
        if (value == null) {
@@ -259,8 +269,8 @@ class SettingsToPropertiesMapper {
    }

    @VisibleForTesting
    void updatePropertyFromSetting(String settingName, String propName, boolean isGlobalSetting) {
        String settingValue = getSetting(settingName, isGlobalSetting);
    void updatePropertyFromSetting(String settingName, String propName) {
        String settingValue = Settings.Global.getString(mContentResolver, settingName);
        setProperty(propName, settingValue);
    }
}
+28 −6
Original line number Diff line number Diff line
@@ -41,11 +41,14 @@ import java.util.Map;

/**
 * Tests for {@link SettingsToPropertiesMapper}
 *
 *  Build/Install/Run:
 *  atest FrameworksServicesTests:SettingsToPropertiesMapperTest
 */
@RunWith(AndroidJUnit4.class)
@SmallTest
public class SettingsToPropertiesMapperTest {
    private static final String NAME_VALID_CHARACTERS_REGEX = "^[\\w\\.\\-@:]*$";
    private static final String NAME_VALID_CHARACTERS_REGEX = "^[\\w\\-@:]*$";
    private static final String[] TEST_MAPPING = new String[] {
            Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS
    };
@@ -77,7 +80,28 @@ public class SettingsToPropertiesMapperTest {
            }
            if (!globalSetting.matches(NAME_VALID_CHARACTERS_REGEX)) {
                Assert.fail(globalSetting + " contains invalid characters. "
                        + "Only alphanumeric characters, '.', '-', '@', ':' and '_' are valid.");
                        + "Only alphanumeric characters, '-', '@', ':' and '_' are valid.");
            }
        }
    }

    @Test
    public void validateRegisteredDeviceConfigScopes() {
        HashSet<String> hashSet = new HashSet<>();
        for (String deviceConfigScope : SettingsToPropertiesMapper.sDeviceConfigScopes) {
            if (hashSet.contains(deviceConfigScope)) {
                Assert.fail("deviceConfigScope "
                        + deviceConfigScope
                        + " is registered more than once in "
                        + "SettingsToPropertiesMapper.sDeviceConfigScopes.");
            }
            hashSet.add(deviceConfigScope);
            if (TextUtils.isEmpty(deviceConfigScope)) {
                Assert.fail("empty deviceConfigScope registered.");
            }
            if (!deviceConfigScope.matches(NAME_VALID_CHARACTERS_REGEX)) {
                Assert.fail(deviceConfigScope + " contains invalid characters. "
                        + "Only alphanumeric characters, '-', '@', ':' and '_' are valid.");
            }
        }
    }
@@ -98,8 +122,7 @@ public class SettingsToPropertiesMapperTest {
                Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS, "testValue2");
        mTestMapper.updatePropertyFromSetting(
                Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS,
                systemPropertyName,
                true);
                systemPropertyName);
        propValue = mTestMapper.systemPropertiesGet(systemPropertyName);
        Assert.assertEquals("testValue2", propValue);

@@ -107,8 +130,7 @@ public class SettingsToPropertiesMapperTest {
                Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS, null);
        mTestMapper.updatePropertyFromSetting(
                Settings.Global.SQLITE_COMPATIBILITY_WAL_FLAGS,
                systemPropertyName,
                true);
                systemPropertyName);
        propValue = mTestMapper.systemPropertiesGet(systemPropertyName);
        Assert.assertEquals("", propValue);
    }