Loading ravenwood/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -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", Loading ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java +9 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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(); Loading Loading @@ -329,7 +334,7 @@ public class RavenwoodRuntimeEnvironmentController { LocalServices.removeAllServicesForTest(); ServiceManager.reset$ravenwood(); setSystemProperties(RavenwoodSystemProperties.DEFAULT_VALUES); setSystemProperties(null); if (sOriginalIdentityToken != -1) { Binder.restoreCallingIdentity(sOriginalIdentityToken); } Loading Loading @@ -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()); Loading ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java +87 −68 Original line number Diff line number Diff line Loading @@ -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<>(); Loading @@ -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() { Loading Loading @@ -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(); Loading Loading @@ -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); } Loading
ravenwood/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -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", Loading
ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java +9 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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(); Loading Loading @@ -329,7 +334,7 @@ public class RavenwoodRuntimeEnvironmentController { LocalServices.removeAllServicesForTest(); ServiceManager.reset$ravenwood(); setSystemProperties(RavenwoodSystemProperties.DEFAULT_VALUES); setSystemProperties(null); if (sOriginalIdentityToken != -1) { Binder.restoreCallingIdentity(sOriginalIdentityToken); } Loading Loading @@ -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()); Loading
ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java +87 −68 Original line number Diff line number Diff line Loading @@ -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<>(); Loading @@ -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() { Loading Loading @@ -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(); Loading Loading @@ -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); }