[Ravenwood] Load default properties from build.prop
Flag: EXEMPT host test change only
Bug: 292141694
Test: $ANDROID_BUILD_TOP/frameworks/base/ravenwood/scripts/run-ravenwood-tests.sh
Change-Id: Ifdd991c7c85d1a81309721dc44017d3b9cad1894
diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp
index bfa801f..8e884bc 100644
--- a/ravenwood/Android.bp
+++ b/ravenwood/Android.bp
@@ -372,6 +372,7 @@
android_ravenwood_libgroup {
name: "ravenwood-runtime",
data: [
+ ":system-build.prop",
":framework-res",
":ravenwood-empty-res",
":framework-platform-compat-config",
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
index 5894476..24950e6 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
@@ -20,12 +20,14 @@
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 @@
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 @@
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 @@
LocalServices.removeAllServicesForTest();
ServiceManager.reset$ravenwood();
- setSystemProperties(RavenwoodSystemProperties.DEFAULT_VALUES);
+ setSystemProperties(null);
if (sOriginalIdentityToken != -1) {
Binder.restoreCallingIdentity(sOriginalIdentityToken);
}
@@ -388,9 +393,10 @@
/**
* 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());
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
index f1e1ef6..ced1519 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
@@ -18,12 +18,94 @@
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 @@
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 @@
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 @@
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);
}