diff options
7 files changed, 165 insertions, 11 deletions
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 45121807b57d..8aa2c35b49e4 100755 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -36,6 +36,8 @@ import android.util.ArraySet; import android.util.Slog; import android.view.View; +import com.android.internal.ravenwood.RavenwoodEnvironment; + import dalvik.system.VMRuntime; import java.util.ArrayList; @@ -49,6 +51,10 @@ import java.util.stream.Collectors; */ @RavenwoodKeepWholeClass public class Build { + static { + // Set up the default system properties. + RavenwoodEnvironment.ensureRavenwoodInitialized(); + } private static final String TAG = "Build"; /** Value used for when a build property is unknown. */ diff --git a/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java b/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java index 4a3dfbe9c0d3..149442556676 100644 --- a/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java +++ b/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java @@ -15,14 +15,23 @@ */ package com.android.internal.ravenwood; +import android.ravenwood.annotation.RavenwoodNativeSubstitutionClass; + /** * Class to interact with the Ravenwood environment. */ @android.ravenwood.annotation.RavenwoodKeepWholeClass -public class RavenwoodEnvironment { +@RavenwoodNativeSubstitutionClass( + "com.android.platform.test.ravenwood.nativesubstitution.RavenwoodEnvironment_host") +public final class RavenwoodEnvironment { + public static final String TAG = "RavenwoodEnvironment"; + private static RavenwoodEnvironment sInstance = new RavenwoodEnvironment(); private RavenwoodEnvironment() { + if (isRunningOnRavenwood()) { + ensureRavenwoodInitializedInternal(); + } } /** @@ -33,6 +42,21 @@ public class RavenwoodEnvironment { } /** + * Initialize the ravenwood environment if it hasn't happened already, if running on Ravenwood. + * + * No-op if called on the device side. + */ + public static void ensureRavenwoodInitialized() { + } + + private static void ensureRavenwoodInitialized$ravenwood() { + getInstance(); // This is enough to initialize the environment. + } + + /** Initialize the ravenwood environment */ + private static native void ensureRavenwoodInitializedInternal(); + + /** * USE IT SPARINGLY! Returns true if it's running on Ravenwood, hostside test environment. * * <p>Using this allows code to behave differently on a real device and on Ravenwood, but diff --git a/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodRuleTest.java b/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodRuleTest.java index 3edca7ea5016..01e90d8672e4 100644 --- a/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodRuleTest.java +++ b/ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodRuleTest.java @@ -18,6 +18,7 @@ package com.android.ravenwoodtest.bivalenttest; import android.platform.test.annotations.DisabledOnNonRavenwood; import android.platform.test.annotations.DisabledOnRavenwood; import android.platform.test.ravenwood.RavenwoodRule; +import android.util.Log; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -43,5 +44,13 @@ public class RavenwoodRuleTest { Assert.assertTrue(RavenwoodRule.isOnRavenwood()); } + @Test + public void testDumpSystemProperties() { + Log.w("XXX", "System properties"); + for (var sp : System.getProperties().entrySet()) { + Log.w("XXX", "" + sp.getKey() + "=" + sp.getValue()); + } + } + // TODO: Add more tests } diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java index 56a3c64a5750..5506a46203d6 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java @@ -100,10 +100,11 @@ public class RavenwoodRuleImpl { android.os.Process.init$ravenwood(rule.mUid, rule.mPid); android.os.Binder.init$ravenwood(); - android.os.SystemProperties.init$ravenwood( - rule.mSystemProperties.getValues(), - rule.mSystemProperties.getKeyReadablePredicate(), - rule.mSystemProperties.getKeyWritablePredicate()); +// android.os.SystemProperties.init$ravenwood( +// rule.mSystemProperties.getValues(), +// rule.mSystemProperties.getKeyReadablePredicate(), +// rule.mSystemProperties.getKeyWritablePredicate()); + setSystemProperties(rule.mSystemProperties); ServiceManager.init$ravenwood(); LocalServices.removeAllServicesForTest(); @@ -157,7 +158,7 @@ public class RavenwoodRuleImpl { LocalServices.removeAllServicesForTest(); ServiceManager.reset$ravenwood(); - android.os.SystemProperties.reset$ravenwood(); + setSystemProperties(RavenwoodSystemProperties.DEFAULT_VALUES); android.os.Binder.reset$ravenwood(); android.os.Process.reset$ravenwood(); @@ -291,4 +292,16 @@ public class RavenwoodRuleImpl { collectMethods(clazz.getSuperclass(), result); } } + + /** + * Set the current configuration to the actual SystemProperties. + */ + public static void setSystemProperties(RavenwoodSystemProperties ravenwoodSystemProperties) { + var clone = new RavenwoodSystemProperties(ravenwoodSystemProperties, true); + + android.os.SystemProperties.init$ravenwood( + clone.getValues(), + clone.getKeyReadablePredicate(), + clone.getKeyWritablePredicate()); + } } diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java index 85ad4e444f24..c3786ee0041d 100644 --- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java +++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java @@ -22,7 +22,9 @@ import java.util.Map; import java.util.Set; import java.util.function.Predicate; -class RavenwoodSystemProperties { +public class RavenwoodSystemProperties { + private volatile boolean mIsImmutable; + private final Map<String, String> mValues = new HashMap<>(); /** Set of additional keys that should be considered readable */ @@ -101,15 +103,23 @@ class RavenwoodSystemProperties { setValue("ro.debuggable", "1"); } - Map<String, String> getValues() { + /** 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; + } + + public Map<String, String> getValues() { return new HashMap<>(mValues); } - Predicate<String> getKeyReadablePredicate() { + public Predicate<String> getKeyReadablePredicate() { return mKeyReadablePredicate; } - Predicate<String> getKeyWritablePredicate() { + public Predicate<String> getKeyWritablePredicate() { return mKeyWritablePredicate; } @@ -123,12 +133,20 @@ class RavenwoodSystemProperties { "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); @@ -136,6 +154,8 @@ class RavenwoodSystemProperties { } public void setValue(String key, Object value) { + ensureNotImmutable(); + final String valueString = (value == null) ? null : String.valueOf(value); if ((valueString == null) || valueString.isEmpty()) { mValues.remove(key); @@ -145,16 +165,19 @@ class RavenwoodSystemProperties { } public void setAccessNone(String key) { + ensureNotImmutable(); mKeyReadable.remove(key); mKeyWritable.remove(key); } public void setAccessReadOnly(String key) { + ensureNotImmutable(); mKeyReadable.add(key); mKeyWritable.remove(key); } public void setAccessReadWrite(String key) { + ensureNotImmutable(); mKeyReadable.add(key); mKeyWritable.add(key); } @@ -172,4 +195,11 @@ 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); +}
\ No newline at end of file diff --git a/ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/nativesubstitution/RavenwoodEnvironment_host.java b/ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/nativesubstitution/RavenwoodEnvironment_host.java new file mode 100644 index 000000000000..68bf92273022 --- /dev/null +++ b/ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/nativesubstitution/RavenwoodEnvironment_host.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.platform.test.ravenwood.nativesubstitution; + +import android.platform.test.ravenwood.RavenwoodSystemProperties; +import android.util.Log; + +import com.android.internal.ravenwood.RavenwoodEnvironment; + +public class RavenwoodEnvironment_host { + private static final String TAG = RavenwoodEnvironment.TAG; + + private static final Object sInitializeLock = new Object(); + + // @GuardedBy("sInitializeLock") + private static boolean sInitialized; + + private RavenwoodEnvironment_host() { + } + + /** + * Called from {@link RavenwoodEnvironment#ensureRavenwoodInitialized()}. + */ + public static void ensureRavenwoodInitializedInternal() { + synchronized (sInitializeLock) { + if (sInitialized) { + return; + } + Log.w(TAG, "Initializing Ravenwood environment"); + + // Set the default values. + var sysProps = RavenwoodSystemProperties.DEFAULT_VALUES; + + // We have a method that does it in RavenwoodRuleImpl, but we can't use that class + // here, So just inline it. + SystemProperties_host.initializeIfNeeded( + sysProps.getValues(), + sysProps.getKeyReadablePredicate(), + sysProps.getKeyWritablePredicate()); + + sInitialized = true; + } + } +} diff --git a/ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/nativesubstitution/SystemProperties_host.java b/ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/nativesubstitution/SystemProperties_host.java index eba6c8b2db64..e7479d313918 100644 --- a/ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/nativesubstitution/SystemProperties_host.java +++ b/ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/nativesubstitution/SystemProperties_host.java @@ -47,6 +47,21 @@ public class SystemProperties_host { @GuardedBy("sLock") private static SparseArray<String> sKeyHandles = new SparseArray<>(); + /** + * Basically the same as {@link #native_init$ravenwood}, but it'll only run if no values are + * set yet. + */ + public static void initializeIfNeeded(Map<String, String> values, + Predicate<String> keyReadablePredicate, Predicate<String> keyWritablePredicate) { + synchronized (sLock) { + if (sValues != null) { + return; // Already initialized. + } + native_init$ravenwood(values, keyReadablePredicate, keyWritablePredicate, + () -> {}); + } + } + public static void native_init$ravenwood(Map<String, String> values, Predicate<String> keyReadablePredicate, Predicate<String> keyWritablePredicate, Runnable changeCallback) { |