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

Commit ec7676d1 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "[Ravenwood] Load default properties from build.prop" into main

parents 56149b13 d69d3ee0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -372,6 +372,7 @@ java_library {
android_ravenwood_libgroup {
    name: "ravenwood-runtime",
    data: [
        ":system-build.prop",
        ":framework-res",
        ":ravenwood-empty-res",
        ":framework-platform-compat-config",
+9 −3
Original line number Diff line number Diff line
@@ -20,12 +20,14 @@ import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_INST_R
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_RESOURCE_APK;
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING;
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERSION_JAVA_SYSPROP;
import static com.android.ravenwood.common.RavenwoodCommonUtils.getRavenwoodRuntimePath;

import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;

import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.Instrumentation;
import android.app.ResourcesManager;
@@ -81,6 +83,8 @@ public class RavenwoodRuntimeEnvironmentController {
    private static final String MAIN_THREAD_NAME = "RavenwoodMain";
    private static final String RAVENWOOD_NATIVE_SYSPROP_NAME = "ravenwood_sysprop";
    private static final String RAVENWOOD_NATIVE_RUNTIME_NAME = "ravenwood_runtime";
    private static final String RAVENWOOD_BUILD_PROP =
            getRavenwoodRuntimePath() + "ravenwood-data/build.prop";

    /**
     * When enabled, attempt to dump all thread stacks just before we hit the
@@ -158,7 +162,8 @@ public class RavenwoodRuntimeEnvironmentController {
        System.load(RavenwoodCommonUtils.getJniLibraryPath(RAVENWOOD_NATIVE_RUNTIME_NAME));

        // Do the basic set up for the android sysprops.
        setSystemProperties(RavenwoodSystemProperties.DEFAULT_VALUES);
        RavenwoodSystemProperties.initialize(RAVENWOOD_BUILD_PROP);
        setSystemProperties(null);

        // Make sure libandroid_runtime is loaded.
        RavenwoodNativeLoader.loadFrameworkNativeCode();
@@ -329,7 +334,7 @@ public class RavenwoodRuntimeEnvironmentController {
        LocalServices.removeAllServicesForTest();
        ServiceManager.reset$ravenwood();

        setSystemProperties(RavenwoodSystemProperties.DEFAULT_VALUES);
        setSystemProperties(null);
        if (sOriginalIdentityToken != -1) {
            Binder.restoreCallingIdentity(sOriginalIdentityToken);
        }
@@ -388,9 +393,10 @@ public class RavenwoodRuntimeEnvironmentController {
    /**
     * Set the current configuration to the actual SystemProperties.
     */
    private static void setSystemProperties(RavenwoodSystemProperties systemProperties) {
    private static void setSystemProperties(@Nullable RavenwoodSystemProperties systemProperties) {
        SystemProperties.clearChangeCallbacksForTest();
        RavenwoodRuntimeNative.clearSystemProperties();
        if (systemProperties == null) systemProperties = new RavenwoodSystemProperties();
        sProps = new RavenwoodSystemProperties(systemProperties, true);
        for (var entry : systemProperties.getValues().entrySet()) {
            RavenwoodRuntimeNative.setSystemProperty(entry.getKey(), entry.getValue());
+87 −68
Original line number Diff line number Diff line
@@ -18,12 +18,94 @@ package android.platform.test.ravenwood;

import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_SYSPROP;

import com.android.ravenwood.common.RavenwoodCommonUtils;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class RavenwoodSystemProperties {
    private static final String TAG = "RavenwoodSystemProperties";

    private static final Map<String, String> sDefaultValues = new HashMap<>();

    private static final String[] PARTITIONS = {
            "bootimage",
            "odm",
            "product",
            "system",
            "system_ext",
            "vendor",
            "vendor_dlkm",
    };

    /**
     * More info about property file loading: system/core/init/property_service.cpp
     * In the following logic, the only partition we would need to consider is "system",
     * since we only read from system-build.prop
     */
    static void initialize(String propFile) {
        // Load all properties from build.prop
        try {
            Files.readAllLines(Path.of(propFile)).stream()
                    .map(String::trim)
                    .filter(s -> !s.startsWith("#"))
                    .map(s -> s.split("\\s*=\\s*", 2))
                    .filter(a -> a.length == 2)
                    .forEach(a -> sDefaultValues.put(a[0], a[1]));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        // If ro.product.${name} is not set, derive from ro.product.${partition}.${name}
        // If ro.product.cpu.abilist* is not set, derive from ro.${partition}.product.cpu.abilist*
        for (var entry : Set.copyOf(sDefaultValues.entrySet())) {
            final String key;
            if (entry.getKey().startsWith("ro.product.system.")) {
                var name = entry.getKey().substring(18);
                key = "ro.product." + name;

            } else if (entry.getKey().startsWith("ro.system.product.cpu.abilist")) {
                var name = entry.getKey().substring(22);
                key = "ro.product.cpu." + name;
            } else {
                continue;
            }
            if (!sDefaultValues.containsKey(key)) {
                sDefaultValues.put(key, entry.getValue());
            }
        }

        // Some other custom values
        sDefaultValues.put("ro.board.first_api_level", "1");
        sDefaultValues.put("ro.product.first_api_level", "1");
        sDefaultValues.put("ro.soc.manufacturer", "Android");
        sDefaultValues.put("ro.soc.model", "Ravenwood");
        sDefaultValues.put(RAVENWOOD_SYSPROP, "1");

        // Log all values
        sDefaultValues.forEach((key, value) -> RavenwoodCommonUtils.log(TAG, key + "=" + value));

        // Copy ro.product.* and ro.build.* to all partitions, just in case
        // We don't want to log these because these are just a lot of duplicate values
        for (var entry : Set.copyOf(sDefaultValues.entrySet())) {
            var key = entry.getKey();
            if (key.startsWith("ro.product.") || key.startsWith("ro.build.")) {
                var name = key.substring(3);
                for (String partition : PARTITIONS) {
                    var newKey = "ro." + partition + "." + name;
                    if (!sDefaultValues.containsKey(newKey)) {
                        sDefaultValues.put(newKey, entry.getValue());
                    }
                }
            }
        }
    }

    private volatile boolean mIsImmutable;

    private final Map<String, String> mValues = new HashMap<>();
@@ -35,47 +117,15 @@ public class RavenwoodSystemProperties {
    private final Set<String> mKeyWritable = new HashSet<>();

    public RavenwoodSystemProperties() {
        // TODO: load these values from build.prop generated files
        setValueForPartitions("product.brand", "Android");
        setValueForPartitions("product.device", "Ravenwood");
        setValueForPartitions("product.manufacturer", "Android");
        setValueForPartitions("product.model", "Ravenwood");
        setValueForPartitions("product.name", "Ravenwood");

        setValueForPartitions("product.cpu.abilist", "x86_64");
        setValueForPartitions("product.cpu.abilist32", "");
        setValueForPartitions("product.cpu.abilist64", "x86_64");

        setValueForPartitions("build.date", "Thu Jan 01 00:00:00 GMT 2024");
        setValueForPartitions("build.date.utc", "1704092400");
        setValueForPartitions("build.id", "MAIN");
        setValueForPartitions("build.tags", "dev-keys");
        setValueForPartitions("build.type", "userdebug");
        setValueForPartitions("build.version.all_codenames", "REL");
        setValueForPartitions("build.version.codename", "REL");
        setValueForPartitions("build.version.incremental", "userdebug.ravenwood.20240101");
        setValueForPartitions("build.version.known_codenames", "REL");
        setValueForPartitions("build.version.release", "14");
        setValueForPartitions("build.version.release_or_codename", "VanillaIceCream");
        setValueForPartitions("build.version.sdk", "34");

        setValue("ro.board.first_api_level", "1");
        setValue("ro.product.first_api_level", "1");

        setValue("ro.soc.manufacturer", "Android");
        setValue("ro.soc.model", "Ravenwood");

        setValue("ro.debuggable", "1");

        setValue(RAVENWOOD_SYSPROP, "1");
        mValues.putAll(sDefaultValues);
    }

    /** Copy constructor */
    public RavenwoodSystemProperties(RavenwoodSystemProperties source, boolean immutable) {
        this.mKeyReadable.addAll(source.mKeyReadable);
        this.mKeyWritable.addAll(source.mKeyWritable);
        this.mValues.putAll(source.mValues);
        this.mIsImmutable = immutable;
        mKeyReadable.addAll(source.mKeyReadable);
        mKeyWritable.addAll(source.mKeyWritable);
        mValues.putAll(source.mValues);
        mIsImmutable = immutable;
    }

    public Map<String, String> getValues() {
@@ -123,36 +173,12 @@ public class RavenwoodSystemProperties {
        return mKeyWritable.contains(key);
    }

    private static final String[] PARTITIONS = {
            "bootimage",
            "odm",
            "product",
            "system",
            "system_ext",
            "vendor",
            "vendor_dlkm",
    };

    private void ensureNotImmutable() {
        if (mIsImmutable) {
            throw new RuntimeException("Unable to update immutable instance");
        }
    }

    /**
     * Set the given property for all possible partitions where it could be defined. For
     * example, the value of {@code ro.build.type} is typically also mirrored under
     * {@code ro.system.build.type}, etc.
     */
    private void setValueForPartitions(String key, String value) {
        ensureNotImmutable();

        setValue("ro." + key, value);
        for (String partition : PARTITIONS) {
            setValue("ro." + partition + "." + key, value);
        }
    }

    public void setValue(String key, Object value) {
        ensureNotImmutable();

@@ -195,11 +221,4 @@ public class RavenwoodSystemProperties {
            return key;
        }
    }

    /**
     * Return an immutable, default instance.
     */
    // Create a default instance, and make an immutable copy of it.
    public static final RavenwoodSystemProperties DEFAULT_VALUES =
            new RavenwoodSystemProperties(new RavenwoodSystemProperties(), true);
}