Skip to content

Commit

Permalink
[Ravenwood] Internal clean up, more PFD APIs, OsConstants, etc
Browse files Browse the repository at this point in the history
- Support a few more ParcelFileDescriptor APIs.
- Support OsConstants and a couple of Os APIs.

- Also clean up f/b/ravenwood. Now we have "runtime-common" library
  that can be used from different components of Ravenwood infra,
  with native code support.

Bug: 292141694
Test: $ANDROID_BUILD_TOP/frameworks/base/ravenwood/scripts/run-ravenwood-tests.sh
Test: CtsOsTestCases (on tree hugger)
Flag: EXEMPT hostside test change only
Change-Id: I259a04201e05e615e17da0529cb500a102887ec9
  • Loading branch information
Makoto Onuki committed May 23, 2024
1 parent 820d81b commit df9cd26
Show file tree
Hide file tree
Showing 31 changed files with 3,418 additions and 255 deletions.
2 changes: 2 additions & 0 deletions Ravenwood.bp
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,8 @@ android_ravenwood_libgroup {
"100-framework-minus-apex.ravenwood",
"200-kxml2-android",

"ravenwood-runtime-common-ravenwood",

"android.test.mock.ravenwood",
"ravenwood-helper-runtime",
"hoststubgen-helper-runtime.ravenwood",
Expand Down
36 changes: 17 additions & 19 deletions core/java/android/os/ParcelFileDescriptor.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
import android.util.Log;
import android.util.Slog;

import com.android.internal.ravenwood.RavenwoodEnvironment;

import dalvik.system.VMRuntime;

import libcore.io.IoUtils;
Expand Down Expand Up @@ -388,7 +390,6 @@ private static void closeInternal(FileDescriptor fd) {
* new file descriptor shared state such as file position with the
* original file descriptor.
*/
@RavenwoodThrow(reason = "Requires JNI support")
public static ParcelFileDescriptor dup(FileDescriptor orig) throws IOException {
try {
final FileDescriptor fd = new FileDescriptor();
Expand All @@ -406,7 +407,6 @@ public static ParcelFileDescriptor dup(FileDescriptor orig) throws IOException {
* new file descriptor shared state such as file position with the
* original file descriptor.
*/
@RavenwoodThrow(reason = "Requires JNI support")
public ParcelFileDescriptor dup() throws IOException {
if (mWrapped != null) {
return mWrapped.dup();
Expand All @@ -425,7 +425,6 @@ public ParcelFileDescriptor dup() throws IOException {
* @return Returns a new ParcelFileDescriptor holding a FileDescriptor
* for a dup of the given fd.
*/
@RavenwoodThrow(reason = "Requires JNI support")
public static ParcelFileDescriptor fromFd(int fd) throws IOException {
final FileDescriptor original = new FileDescriptor();
setFdInt(original, fd);
Expand Down Expand Up @@ -485,7 +484,7 @@ public static ParcelFileDescriptor adoptFd(int fd) {
*
* @throws UncheckedIOException if {@link #dup(FileDescriptor)} throws IOException.
*/
@RavenwoodThrow(reason = "Requires JNI support")
@RavenwoodThrow(reason = "Socket.getFileDescriptor$()")
public static ParcelFileDescriptor fromSocket(Socket socket) {
FileDescriptor fd = socket.getFileDescriptor$();
try {
Expand Down Expand Up @@ -519,7 +518,7 @@ public static ParcelFileDescriptor fromSocket(Socket socket) {
*
* @throws UncheckedIOException if {@link #dup(FileDescriptor)} throws IOException.
*/
@RavenwoodThrow(reason = "Requires JNI support")
@RavenwoodThrow(reason = "DatagramSocket.getFileDescriptor$()")
public static ParcelFileDescriptor fromDatagramSocket(DatagramSocket datagramSocket) {
FileDescriptor fd = datagramSocket.getFileDescriptor$();
try {
Expand All @@ -534,7 +533,6 @@ public static ParcelFileDescriptor fromDatagramSocket(DatagramSocket datagramSoc
* ParcelFileDescriptor in the returned array is the read side; the second
* is the write side.
*/
@RavenwoodThrow(reason = "Requires JNI support")
public static ParcelFileDescriptor[] createPipe() throws IOException {
try {
final FileDescriptor[] fds = Os.pipe2(ifAtLeastQ(O_CLOEXEC));
Expand All @@ -556,7 +554,6 @@ public static ParcelFileDescriptor[] createPipe() throws IOException {
* calling {@link #checkError()}, usually after detecting an EOF.
* This can also be used to detect remote crashes.
*/
@RavenwoodThrow(reason = "Requires JNI support")
public static ParcelFileDescriptor[] createReliablePipe() throws IOException {
try {
final FileDescriptor[] comm = createCommSocketPair();
Expand All @@ -573,15 +570,15 @@ public static ParcelFileDescriptor[] createReliablePipe() throws IOException {
* Create two ParcelFileDescriptors structured as a pair of sockets
* connected to each other. The two sockets are indistinguishable.
*/
@RavenwoodThrow(reason = "Requires JNI support")
@RavenwoodThrow(reason = "Os.socketpair()")
public static ParcelFileDescriptor[] createSocketPair() throws IOException {
return createSocketPair(SOCK_STREAM);
}

/**
* @hide
*/
@RavenwoodThrow(reason = "Requires JNI support")
@RavenwoodThrow(reason = "Os.socketpair()")
public static ParcelFileDescriptor[] createSocketPair(int type) throws IOException {
try {
final FileDescriptor fd0 = new FileDescriptor();
Expand All @@ -604,15 +601,15 @@ public static ParcelFileDescriptor[] createSocketPair(int type) throws IOExcepti
* calling {@link #checkError()}, usually after detecting an EOF.
* This can also be used to detect remote crashes.
*/
@RavenwoodThrow(reason = "Requires JNI support")
@RavenwoodThrow(reason = "Os.socketpair()")
public static ParcelFileDescriptor[] createReliableSocketPair() throws IOException {
return createReliableSocketPair(SOCK_STREAM);
}

/**
* @hide
*/
@RavenwoodThrow(reason = "Requires JNI support")
@RavenwoodThrow(reason = "Os.socketpair()")
public static ParcelFileDescriptor[] createReliableSocketPair(int type) throws IOException {
try {
final FileDescriptor[] comm = createCommSocketPair();
Expand All @@ -627,7 +624,7 @@ public static ParcelFileDescriptor[] createReliableSocketPair(int type) throws I
}
}

@RavenwoodThrow(reason = "Requires JNI support")
@RavenwoodThrow(reason = "Os.socketpair()")
private static FileDescriptor[] createCommSocketPair() throws IOException {
try {
// Use SOCK_SEQPACKET so that we have a guarantee that the status
Expand Down Expand Up @@ -656,7 +653,7 @@ private static FileDescriptor[] createCommSocketPair() throws IOException {
*/
@UnsupportedAppUsage
@Deprecated
@RavenwoodThrow(reason = "Requires JNI support")
@RavenwoodThrow(blockedBy = MemoryFile.class)
public static ParcelFileDescriptor fromData(byte[] data, String name) throws IOException {
if (data == null) return null;
MemoryFile file = new MemoryFile(name, data.length);
Expand Down Expand Up @@ -712,7 +709,7 @@ public static int parseMode(String mode) {
* @hide
*/
@TestApi
@RavenwoodThrow(reason = "Requires kernel support")
@RavenwoodThrow(reason = "Os.readlink() and Os.stat()")
public static File getFile(FileDescriptor fd) throws IOException {
try {
final String path = Os.readlink("/proc/self/fd/" + getFdInt(fd));
Expand Down Expand Up @@ -744,7 +741,7 @@ public FileDescriptor getFileDescriptor() {
* Return the total size of the file representing this fd, as determined by
* {@code stat()}. Returns -1 if the fd is not a file.
*/
@RavenwoodThrow(reason = "Requires JNI support")
@RavenwoodThrow(reason = "Os.readlink() and Os.stat()")
public long getStatSize() {
if (mWrapped != null) {
return mWrapped.getStatSize();
Expand All @@ -769,7 +766,6 @@ public long getStatSize() {
* @hide
*/
@UnsupportedAppUsage
@RavenwoodThrow(reason = "Requires JNI support")
public long seekTo(long pos) throws IOException {
if (mWrapped != null) {
return mWrapped.seekTo(pos);
Expand Down Expand Up @@ -1037,7 +1033,6 @@ public void checkError() throws IOException {
* take care of calling {@link ParcelFileDescriptor#close
* ParcelFileDescriptor.close()} for you when the stream is closed.
*/
@RavenwoodKeepWholeClass
public static class AutoCloseInputStream extends FileInputStream {
private final ParcelFileDescriptor mPfd;

Expand Down Expand Up @@ -1326,12 +1321,15 @@ private int acquireRawFd(FileDescriptor fd) {

}

@RavenwoodThrow
@RavenwoodReplace
private static boolean isAtLeastQ() {
return (VMRuntime.getRuntime().getTargetSdkVersion() >= Build.VERSION_CODES.Q);
}

@RavenwoodThrow
private static boolean isAtLeastQ$ravenwood() {
return RavenwoodEnvironment.workaround().isTargetSdkAtLeastQ();
}

private static int ifAtLeastQ(int value) {
return isAtLeastQ() ? value : 0;
}
Expand Down
27 changes: 27 additions & 0 deletions core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ public final class RavenwoodEnvironment {
public static final String TAG = "RavenwoodEnvironment";

private static RavenwoodEnvironment sInstance = new RavenwoodEnvironment();
private static Workaround sWorkaround = new Workaround();

private RavenwoodEnvironment() {
if (isRunningOnRavenwood()) {
Expand Down Expand Up @@ -76,4 +77,30 @@ public boolean isRunningOnRavenwood() {
private boolean isRunningOnRavenwood$ravenwood() {
return true;
}

/**
* See {@link Workaround}. It's only usablke on Ravenwood.
*/
public static Workaround workaround() {
if (getInstance().isRunningOnRavenwood()) {
return sWorkaround;
}
throw new IllegalStateException("Workaround can only be used on Ravenwood");
}

/**
* A set of APIs used to work around missing features on Ravenwood. Ideally, this class should
* be empty, and all its APIs should be able to be implemented properly.
*/
public static class Workaround {
Workaround() {
}

/**
* @return whether the app's target SDK level is at least Q.
*/
public boolean isTargetSdkAtLeastQ() {
return true;
}
}
}
51 changes: 50 additions & 1 deletion ravenwood/Android.bp
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,52 @@ java_library {
visibility: ["//visibility:public"],
}

// This and the next module contain the same classes with different implementations.
// "ravenwood-runtime-common-device" will be statically linked in device side tests.
// "ravenwood-runtime-common-ravenwood" will only exist in ravenwood-runtime, which will take
// precedence even if the test jar (accidentally) contains "ravenwood-runtime-common-device".
// "ravenwood-runtime-common" uses it to detect if the rutime is Ravenwood or not.
java_library {
name: "ravenwood-runtime-common-ravenwood",
host_supported: true,
sdk_version: "core_current",
srcs: [
"runtime-common-ravenwood-src/**/*.java",
],
visibility: ["//frameworks/base"],
}

java_library {
name: "ravenwood-runtime-common-device",
host_supported: true,
sdk_version: "core_current",
srcs: [
"runtime-common-device-src/**/*.java",
],
visibility: ["//visibility:private"],
}

java_library {
name: "ravenwood-runtime-common",
host_supported: true,
sdk_version: "core_current",
srcs: [
"runtime-common-src/**/*.java",
],
libs: [
"ravenwood-runtime-common-ravenwood",
],
visibility: ["//visibility:private"],
}

java_library_host {
name: "ravenwood-helper-libcore-runtime.host",
srcs: [
"runtime-helper-src/libcore-fake/**/*.java",
],
static_libs: [
"ravenwood-runtime-common",
],
visibility: ["//visibility:private"],
}

Expand All @@ -77,6 +118,9 @@ java_library {
srcs: [
"runtime-helper-src/framework/**/*.java",
],
static_libs: [
"ravenwood-runtime-common",
],
libs: [
"framework-minus-apex.ravenwood",
"ravenwood-junit",
Expand Down Expand Up @@ -105,6 +149,7 @@ java_library {
],
static_libs: [
"androidx.test.monitor-for-device",
"ravenwood-runtime-common",
],
libs: [
"android.test.mock",
Expand Down Expand Up @@ -145,6 +190,10 @@ java_library {
"junit-flag-src/**/*.java",
],
sdk_version: "test_current",
static_libs: [
"ravenwood-runtime-common",
"ravenwood-runtime-common-device",
],
libs: [
"junit",
"flag-junit",
Expand Down Expand Up @@ -199,7 +248,7 @@ cc_library_shared {
],

srcs: [
"runtime-helper-src/jni/*.cpp",
"runtime-jni/*.cpp",
],

shared_libs: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,6 @@ public class RavenwoodRuleImpl {
sPendingUncaughtException.compareAndSet(null, throwable);
};

public static boolean isOnRavenwood() {
return true;
}

public static void init(RavenwoodRule rule) {
if (ENABLE_UNCAUGHT_EXCEPTION_DETECTION) {
maybeThrowPendingUncaughtException(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import android.platform.test.annotations.EnabledOnRavenwood;
import android.platform.test.annotations.IgnoreUnderRavenwood;

import com.android.ravenwood.common.RavenwoodCommonUtils;

import org.junit.Assume;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
Expand All @@ -54,7 +56,7 @@
* before a test class is fully initialized.
*/
public class RavenwoodRule implements TestRule {
static final boolean IS_ON_RAVENWOOD = RavenwoodRuleImpl.isOnRavenwood();
static final boolean IS_ON_RAVENWOOD = RavenwoodCommonUtils.isOnRavenwood();

/**
* When probing is enabled, all tests will be unconditionally run on Ravenwood to detect
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package android.platform.test.ravenwood;

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

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
Expand Down Expand Up @@ -101,6 +103,8 @@ public RavenwoodSystemProperties() {
setValue("ro.soc.model", "Ravenwood");

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

setValue(RAVENWOOD_SYSPROP, "1");
}

/** Copy constructor */
Expand Down
Loading

0 comments on commit df9cd26

Please sign in to comment.