summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcore/java/android/os/Build.java6
-rw-r--r--core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java26
-rw-r--r--ravenwood/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodRuleTest.java9
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuleImpl.java23
-rw-r--r--ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java40
-rw-r--r--ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/nativesubstitution/RavenwoodEnvironment_host.java57
-rw-r--r--ravenwood/runtime-helper-src/framework/com/android/platform/test/ravenwood/nativesubstitution/SystemProperties_host.java15
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) {