diff options
author | 2024-11-01 23:46:59 +0000 | |
---|---|---|
committer | 2024-11-01 23:46:59 +0000 | |
commit | 77754502f5ee02cc2f66bfb95416b60ded107ca4 (patch) | |
tree | 9b087c8120209ad8b162c6f0963c4932594f5949 | |
parent | ebb295244d0c24dc9eb4eecd871961bbf527f15b (diff) | |
parent | 41adec2334d6610ba1127cad335a3f29791e4920 (diff) |
Merge "[Ravenwood] Cleanup and update RavenwoodEnvironment" into main
17 files changed, 327 insertions, 172 deletions
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 30d2dec8b4c4..3c3a4fd68b15 100644 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -36,8 +36,6 @@ 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; @@ -51,10 +49,6 @@ 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/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java index e80efd2a9380..60eeb2b8b0d5 100644 --- a/core/java/android/os/ParcelFileDescriptor.java +++ b/core/java/android/os/ParcelFileDescriptor.java @@ -41,7 +41,6 @@ import android.content.ContentResolver; import android.net.Uri; import android.os.MessageQueue.OnFileDescriptorEventListener; import android.ravenwood.annotation.RavenwoodKeepWholeClass; -import android.ravenwood.annotation.RavenwoodReplace; import android.ravenwood.annotation.RavenwoodThrow; import android.system.ErrnoException; import android.system.Os; @@ -51,8 +50,6 @@ import android.util.CloseGuard; import android.util.Log; import android.util.Slog; -import com.android.internal.ravenwood.RavenwoodEnvironment; - import dalvik.system.VMRuntime; import libcore.io.IoUtils; @@ -1254,15 +1251,10 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { } } - @RavenwoodReplace private static boolean isAtLeastQ() { return (VMRuntime.getRuntime().getTargetSdkVersion() >= Build.VERSION_CODES.Q); } - private static boolean isAtLeastQ$ravenwood() { - return RavenwoodEnvironment.workaround().isTargetSdkAtLeastQ(); - } - private static int ifAtLeastQ(int value) { return isAtLeastQ() ? value : 0; } diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index cd8788db4e70..851953af1fb9 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -29,6 +29,11 @@ import android.annotation.TestApi; import android.annotation.UptimeMillisLong; import android.compat.annotation.UnsupportedAppUsage; import android.os.Build.VERSION_CODES; +import android.ravenwood.annotation.RavenwoodKeep; +import android.ravenwood.annotation.RavenwoodKeepPartialClass; +import android.ravenwood.annotation.RavenwoodRedirect; +import android.ravenwood.annotation.RavenwoodRedirectionClass; +import android.ravenwood.annotation.RavenwoodReplace; import android.sysprop.MemoryProperties; import android.system.ErrnoException; import android.system.Os; @@ -37,8 +42,6 @@ import android.system.StructPollfd; import android.util.Pair; import android.webkit.WebViewZygote; -import com.android.internal.os.SomeArgs; -import com.android.internal.util.Preconditions; import com.android.sdksandbox.flags.Flags; import dalvik.system.VMDebug; @@ -55,6 +58,8 @@ import java.util.concurrent.TimeoutException; /** * Tools for managing OS processes. */ +@RavenwoodKeepPartialClass +@RavenwoodRedirectionClass("Process_ravenwood") public class Process { private static final String LOG_TAG = "Process"; @@ -672,7 +677,6 @@ public class Process { */ public static final ZygoteProcess ZYGOTE_PROCESS = new ZygoteProcess(); - /** * The process name set via {@link #setArgV0(String)}. */ @@ -846,47 +850,20 @@ public class Process { /** * Returns true if the current process is a 64-bit runtime. */ - @android.ravenwood.annotation.RavenwoodKeep + @RavenwoodKeep public static final boolean is64Bit() { return VMRuntime.getRuntime().is64Bit(); } - private static volatile ThreadLocal<SomeArgs> sIdentity$ravenwood; - - /** @hide */ - @android.ravenwood.annotation.RavenwoodKeep - public static void init$ravenwood(final int uid, final int pid) { - sIdentity$ravenwood = ThreadLocal.withInitial(() -> { - final SomeArgs args = SomeArgs.obtain(); - args.argi1 = uid; - args.argi2 = pid; - args.argi3 = Long.hashCode(Thread.currentThread().getId()); - args.argi4 = THREAD_PRIORITY_DEFAULT; - args.arg1 = Boolean.TRUE; // backgroundOk - return args; - }); - } - - /** @hide */ - @android.ravenwood.annotation.RavenwoodKeep - public static void reset$ravenwood() { - sIdentity$ravenwood = null; - } - /** * Returns the identifier of this process, which can be used with * {@link #killProcess} and {@link #sendSignal}. */ - @android.ravenwood.annotation.RavenwoodReplace + @RavenwoodKeep public static final int myPid() { return Os.getpid(); } - /** @hide */ - public static final int myPid$ravenwood() { - return Preconditions.requireNonNullViaRavenwoodRule(sIdentity$ravenwood).get().argi2; - } - /** * Returns the identifier of this process' parent. * @hide @@ -900,39 +877,29 @@ public class Process { * Returns the identifier of the calling thread, which be used with * {@link #setThreadPriority(int, int)}. */ - @android.ravenwood.annotation.RavenwoodReplace + @RavenwoodKeep public static final int myTid() { return Os.gettid(); } - /** @hide */ - public static final int myTid$ravenwood() { - return Preconditions.requireNonNullViaRavenwoodRule(sIdentity$ravenwood).get().argi3; - } - /** * Returns the identifier of this process's uid. This is the kernel uid * that the process is running under, which is the identity of its * app-specific sandbox. It is different from {@link #myUserHandle} in that * a uid identifies a specific app sandbox in a specific user. */ - @android.ravenwood.annotation.RavenwoodReplace + @RavenwoodKeep public static final int myUid() { return Os.getuid(); } - /** @hide */ - public static final int myUid$ravenwood() { - return Preconditions.requireNonNullViaRavenwoodRule(sIdentity$ravenwood).get().argi1; - } - /** * Returns this process's user handle. This is the * user the process is running under. It is distinct from * {@link #myUid()} in that a particular user will have multiple * distinct apps running under it each with their own uid. */ - @android.ravenwood.annotation.RavenwoodKeep + @RavenwoodKeep public static UserHandle myUserHandle() { return UserHandle.of(UserHandle.getUserId(myUid())); } @@ -941,7 +908,7 @@ public class Process { * Returns whether the given uid belongs to a system core component or not. * @hide */ - @android.ravenwood.annotation.RavenwoodKeep + @RavenwoodKeep public static boolean isCoreUid(int uid) { return UserHandle.isCore(uid); } @@ -952,7 +919,7 @@ public class Process { * @return Whether the uid corresponds to an application sandbox running in * a specific user. */ - @android.ravenwood.annotation.RavenwoodKeep + @RavenwoodKeep public static boolean isApplicationUid(int uid) { return UserHandle.isApp(uid); } @@ -960,7 +927,7 @@ public class Process { /** * Returns whether the current process is in an isolated sandbox. */ - @android.ravenwood.annotation.RavenwoodKeep + @RavenwoodKeep public static final boolean isIsolated() { return isIsolated(myUid()); } @@ -972,7 +939,7 @@ public class Process { @Deprecated @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.TIRAMISU, publicAlternatives = "Use {@link #isIsolatedUid(int)} instead.") - @android.ravenwood.annotation.RavenwoodKeep + @RavenwoodKeep public static final boolean isIsolated(int uid) { return isIsolatedUid(uid); } @@ -980,7 +947,7 @@ public class Process { /** * Returns whether the process with the given {@code uid} is an isolated sandbox. */ - @android.ravenwood.annotation.RavenwoodKeep + @RavenwoodKeep public static final boolean isIsolatedUid(int uid) { uid = UserHandle.getAppId(uid); return (uid >= FIRST_ISOLATED_UID && uid <= LAST_ISOLATED_UID) @@ -992,7 +959,7 @@ public class Process { * @see android.app.sdksandbox.SdkSandboxManager */ @SuppressLint("UnflaggedApi") // promoting from @SystemApi. - @android.ravenwood.annotation.RavenwoodKeep + @RavenwoodKeep public static final boolean isSdkSandboxUid(int uid) { uid = UserHandle.getAppId(uid); return (uid >= FIRST_SDK_SANDBOX_UID && uid <= LAST_SDK_SANDBOX_UID); @@ -1008,7 +975,7 @@ public class Process { * @throws IllegalArgumentException if input is not an sdk sandbox uid */ @SuppressLint("UnflaggedApi") // promoting from @SystemApi. - @android.ravenwood.annotation.RavenwoodKeep + @RavenwoodKeep public static final int getAppUidForSdkSandboxUid(int uid) { if (!isSdkSandboxUid(uid)) { throw new IllegalArgumentException("Input UID is not an SDK sandbox UID"); @@ -1024,7 +991,7 @@ public class Process { */ @SystemApi(client = MODULE_LIBRARIES) @TestApi - @android.ravenwood.annotation.RavenwoodKeep + @RavenwoodKeep // TODO(b/318651609): Deprecate once Process#getSdkSandboxUidForAppUid is rolled out to 100% public static final int toSdkSandboxUid(int uid) { return uid + (FIRST_SDK_SANDBOX_UID - FIRST_APPLICATION_UID); @@ -1040,7 +1007,7 @@ public class Process { * @throws IllegalArgumentException if input is not an app uid */ @FlaggedApi(Flags.FLAG_SDK_SANDBOX_UID_TO_APP_UID_API) - @android.ravenwood.annotation.RavenwoodKeep + @RavenwoodKeep public static final int getSdkSandboxUidForAppUid(int uid) { if (!isApplicationUid(uid)) { throw new IllegalArgumentException("Input UID is not an app UID"); @@ -1051,7 +1018,7 @@ public class Process { /** * Returns whether the current process is a sdk sandbox process. */ - @android.ravenwood.annotation.RavenwoodKeep + @RavenwoodKeep public static final boolean isSdkSandbox() { return isSdkSandboxUid(myUid()); } @@ -1128,28 +1095,11 @@ public class Process { * not have permission to modify the given thread, or to use the given * priority. */ - @android.ravenwood.annotation.RavenwoodReplace + @RavenwoodRedirect public static final native void setThreadPriority(int tid, @IntRange(from = -20, to = THREAD_PRIORITY_LOWEST) int priority) throws IllegalArgumentException, SecurityException; - /** @hide */ - public static final void setThreadPriority$ravenwood(int tid, int priority) { - final SomeArgs args = - Preconditions.requireNonNullViaRavenwoodRule(sIdentity$ravenwood).get(); - if (args.argi3 == tid) { - boolean backgroundOk = (args.arg1 == Boolean.TRUE); - if (priority >= THREAD_PRIORITY_BACKGROUND && !backgroundOk) { - throw new IllegalArgumentException( - "Priority " + priority + " blocked by setCanSelfBackground()"); - } - args.argi4 = priority; - } else { - throw new UnsupportedOperationException( - "Cross-thread priority management not yet available in Ravenwood"); - } - } - /** * Call with 'false' to cause future calls to {@link #setThreadPriority(int)} to * throw an exception if passed a background-level thread priority. This is only @@ -1157,16 +1107,9 @@ public class Process { * * @hide */ - @android.ravenwood.annotation.RavenwoodReplace + @RavenwoodRedirect public static final native void setCanSelfBackground(boolean backgroundOk); - /** @hide */ - public static final void setCanSelfBackground$ravenwood(boolean backgroundOk) { - final SomeArgs args = - Preconditions.requireNonNullViaRavenwoodRule(sIdentity$ravenwood).get(); - args.arg1 = Boolean.valueOf(backgroundOk); - } - /** * Sets the scheduling group for a thread. * @hide @@ -1295,13 +1238,12 @@ public class Process { * * @see #setThreadPriority(int, int) */ - @android.ravenwood.annotation.RavenwoodReplace + @RavenwoodReplace public static final native void setThreadPriority( @IntRange(from = -20, to = THREAD_PRIORITY_LOWEST) int priority) throws IllegalArgumentException, SecurityException; - /** @hide */ - public static final void setThreadPriority$ravenwood(int priority) { + private static void setThreadPriority$ravenwood(int priority) { setThreadPriority(myTid(), priority); } @@ -1318,23 +1260,11 @@ public class Process { * @throws IllegalArgumentException Throws IllegalArgumentException if * <var>tid</var> does not exist. */ - @android.ravenwood.annotation.RavenwoodReplace + @RavenwoodRedirect @IntRange(from = -20, to = THREAD_PRIORITY_LOWEST) public static final native int getThreadPriority(int tid) throws IllegalArgumentException; - /** @hide */ - public static final int getThreadPriority$ravenwood(int tid) { - final SomeArgs args = - Preconditions.requireNonNullViaRavenwoodRule(sIdentity$ravenwood).get(); - if (args.argi3 == tid) { - return args.argi4; - } else { - throw new UnsupportedOperationException( - "Cross-thread priority management not yet available in Ravenwood"); - } - } - /** * Return the current scheduling policy of a thread, based on Linux. * diff --git a/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java b/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java index 30b160ab161b..a69d2e4f4dca 100644 --- a/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java +++ b/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java @@ -28,19 +28,9 @@ import android.ravenwood.annotation.RavenwoodReplace; public final class RavenwoodEnvironment { public static final String TAG = "RavenwoodEnvironment"; - private static final RavenwoodEnvironment sInstance; - private static final Workaround sWorkaround; + private static RavenwoodEnvironment sInstance = new RavenwoodEnvironment(); - private RavenwoodEnvironment() { - } - - static { - sInstance = new RavenwoodEnvironment(); - sWorkaround = new Workaround(); - ensureRavenwoodInitialized(); - } - - public static RuntimeException notSupportedOnDevice() { + private static RuntimeException notSupportedOnDevice() { return new UnsupportedOperationException("This method can only be used on Ravenwood"); } @@ -52,15 +42,6 @@ public final class RavenwoodEnvironment { } /** - * Initialize the ravenwood environment if it hasn't happened already, if running on Ravenwood. - * - * No-op if called on the device side. - */ - @RavenwoodRedirect - public static void ensureRavenwoodInitialized() { - } - - /** * 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 @@ -91,38 +72,10 @@ public final class RavenwoodEnvironment { } /** - * See {@link Workaround}. It's only usable on Ravenwood. - */ - @RavenwoodReplace - public static Workaround workaround() { - throw notSupportedOnDevice(); - } - - private static Workaround workaround$ravenwood() { - return sWorkaround; - } - - /** * @return the "ravenwood-runtime" directory. */ @RavenwoodRedirect public String getRavenwoodRuntimePath() { throw notSupportedOnDevice(); } - - /** - * 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; - } - } } 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 0f163524d2fe..9752ff3c4358 100644 --- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java +++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java @@ -40,6 +40,7 @@ import android.os.Build; import android.os.Bundle; import android.os.HandlerThread; import android.os.Looper; +import android.os.Process_ravenwood; import android.os.ServiceManager; import android.os.SystemProperties; import android.provider.DeviceConfig_host; @@ -52,6 +53,7 @@ import androidx.test.platform.app.InstrumentationRegistry; import com.android.hoststubgen.hosthelper.HostTestUtils; import com.android.internal.os.RuntimeInit; import com.android.ravenwood.RavenwoodRuntimeNative; +import com.android.ravenwood.RavenwoodRuntimeState; import com.android.ravenwood.common.RavenwoodCommonUtils; import com.android.ravenwood.common.RavenwoodRuntimeException; import com.android.ravenwood.common.SneakyThrow; @@ -223,7 +225,9 @@ public class RavenwoodRuntimeEnvironmentController { Thread.setDefaultUncaughtExceptionHandler(sUncaughtExceptionHandler); } - android.os.Process.init$ravenwood(config.mUid, config.mPid); + RavenwoodRuntimeState.sUid = config.mUid; + RavenwoodRuntimeState.sPid = config.mPid; + RavenwoodRuntimeState.sTargetSdkLevel = config.mTargetSdkLevel; sOriginalIdentityToken = Binder.clearCallingIdentity(); reinit(); setSystemProperties(config.mSystemProperties); @@ -350,8 +354,8 @@ public class RavenwoodRuntimeEnvironmentController { if (sOriginalIdentityToken != -1) { Binder.restoreCallingIdentity(sOriginalIdentityToken); } - android.os.Process.reset$ravenwood(); - + RavenwoodRuntimeState.reset(); + Process_ravenwood.reset(); DeviceConfig_host.reset(); try { diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java index 37b0abcceede..d8f2b705d539 100644 --- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java +++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java @@ -23,6 +23,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.Instrumentation; import android.content.Context; +import android.os.Build; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; @@ -67,7 +68,7 @@ public final class RavenwoodConfig { String mTargetPackageName; int mMinSdkLevel; - int mTargetSdkLevel; + int mTargetSdkLevel = Build.VERSION_CODES.CUR_DEVELOPMENT; boolean mProvideMainThread = false; diff --git a/ravenwood/runtime-helper-src/framework/android/os/Process_ravenwood.java b/ravenwood/runtime-helper-src/framework/android/os/Process_ravenwood.java new file mode 100644 index 000000000000..3c6a4d78d1d9 --- /dev/null +++ b/ravenwood/runtime-helper-src/framework/android/os/Process_ravenwood.java @@ -0,0 +1,70 @@ +/* + * 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 android.os; + +import android.util.Pair; + +public class Process_ravenwood { + + private static volatile ThreadLocal<Pair<Integer, Boolean>> sThreadPriority; + + static { + reset(); + } + + public static void reset() { + // Reset the thread local variable + sThreadPriority = ThreadLocal.withInitial( + () -> Pair.create(Process.THREAD_PRIORITY_DEFAULT, true)); + } + + /** + * Called by {@link Process#setThreadPriority(int, int)} + */ + public static void setThreadPriority(int tid, int priority) { + if (Process.myTid() == tid) { + boolean backgroundOk = sThreadPriority.get().second; + if (priority >= Process.THREAD_PRIORITY_BACKGROUND && !backgroundOk) { + throw new IllegalArgumentException( + "Priority " + priority + " blocked by setCanSelfBackground()"); + } + sThreadPriority.set(Pair.create(priority, backgroundOk)); + } else { + throw new UnsupportedOperationException( + "Cross-thread priority management not yet available in Ravenwood"); + } + } + + /** + * Called by {@link Process#setCanSelfBackground(boolean)} + */ + public static void setCanSelfBackground(boolean backgroundOk) { + int priority = sThreadPriority.get().first; + sThreadPriority.set(Pair.create(priority, backgroundOk)); + } + + /** + * Called by {@link Process#getThreadPriority(int)} + */ + public static int getThreadPriority(int tid) { + if (Process.myTid() == tid) { + return sThreadPriority.get().first; + } else { + throw new UnsupportedOperationException( + "Cross-thread priority management not yet available in Ravenwood"); + } + } +} diff --git a/ravenwood/runtime-helper-src/framework/com/android/internal/ravenwood/RavenwoodEnvironment_host.java b/ravenwood/runtime-helper-src/framework/com/android/internal/ravenwood/RavenwoodEnvironment_host.java index e12ff240c4d9..b65668b67e03 100644 --- a/ravenwood/runtime-helper-src/framework/com/android/internal/ravenwood/RavenwoodEnvironment_host.java +++ b/ravenwood/runtime-helper-src/framework/com/android/internal/ravenwood/RavenwoodEnvironment_host.java @@ -23,14 +23,6 @@ public class RavenwoodEnvironment_host { } /** - * Called from {@link RavenwoodEnvironment#ensureRavenwoodInitialized()}. - */ - public static void ensureRavenwoodInitialized() { - // Initialization is now done by RavenwoodAwareTestRunner. - // Should we remove it? - } - - /** * Called from {@link RavenwoodEnvironment#getRavenwoodRuntimePath()}. */ public static String getRavenwoodRuntimePath(RavenwoodEnvironment env) { diff --git a/ravenwood/runtime-helper-src/libcore-fake/android/system/Os.java b/ravenwood/runtime-helper-src/libcore-fake/android/system/Os.java index c94ef31a5e5e..02981713674d 100644 --- a/ravenwood/runtime-helper-src/libcore-fake/android/system/Os.java +++ b/ravenwood/runtime-helper-src/libcore-fake/android/system/Os.java @@ -16,6 +16,7 @@ package android.system; import com.android.ravenwood.RavenwoodRuntimeNative; +import com.android.ravenwood.RavenwoodRuntimeState; import com.android.ravenwood.common.JvmWorkaround; import java.io.FileDescriptor; @@ -97,4 +98,16 @@ public final class Os { public static void setenv(String name, String value, boolean overwrite) throws ErrnoException { RavenwoodRuntimeNative.setenv(name, value, overwrite); } + + public static int getpid() { + return RavenwoodRuntimeState.sPid; + } + + public static int getuid() { + return RavenwoodRuntimeState.sUid; + } + + public static int gettid() { + return RavenwoodRuntimeNative.gettid(); + } } diff --git a/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java index f13189f6f8be..7b940b423b69 100644 --- a/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java +++ b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeNative.java @@ -58,6 +58,8 @@ public class RavenwoodRuntimeNative { public static native void clearSystemProperties(); + public static native int gettid(); + public static long lseek(FileDescriptor fd, long offset, int whence) throws ErrnoException { return nLseek(JvmWorkaround.getInstance().getFdInt(fd), offset, whence); } diff --git a/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeState.java b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeState.java new file mode 100644 index 000000000000..175e020d61d6 --- /dev/null +++ b/ravenwood/runtime-helper-src/libcore-fake/com/android/ravenwood/RavenwoodRuntimeState.java @@ -0,0 +1,35 @@ +/* + * 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.ravenwood; + +public class RavenwoodRuntimeState { + // This must match VMRuntime.SDK_VERSION_CUR_DEVELOPMENT. + public static final int CUR_DEVELOPMENT = 10000; + + public static volatile int sUid; + public static volatile int sPid; + public static volatile int sTargetSdkLevel; + + static { + reset(); + } + + public static void reset() { + sUid = -1; + sPid = -1; + sTargetSdkLevel = CUR_DEVELOPMENT; + } +} diff --git a/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/VMRuntime.java b/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/VMRuntime.java index ba89f71dde8a..eaadac6a8b92 100644 --- a/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/VMRuntime.java +++ b/ravenwood/runtime-helper-src/libcore-fake/dalvik/system/VMRuntime.java @@ -19,6 +19,7 @@ package dalvik.system; // The original is here: // $ANDROID_BUILD_TOP/libcore/libart/src/main/java/dalvik/system/VMRuntime.java +import com.android.ravenwood.RavenwoodRuntimeState; import com.android.ravenwood.common.JvmWorkaround; import java.lang.reflect.Array; @@ -52,4 +53,8 @@ public class VMRuntime { public long addressOf(Object obj) { return JvmWorkaround.getInstance().addressOf(obj); } + + public int getTargetSdkVersion() { + return RavenwoodRuntimeState.sTargetSdkLevel; + } } diff --git a/ravenwood/runtime-jni/ravenwood_runtime.cpp b/ravenwood/runtime-jni/ravenwood_runtime.cpp index 2a3c26ed3ea3..5b75e9854758 100644 --- a/ravenwood/runtime-jni/ravenwood_runtime.cpp +++ b/ravenwood/runtime-jni/ravenwood_runtime.cpp @@ -17,6 +17,7 @@ #include <fcntl.h> #include <string.h> #include <sys/stat.h> +#include <sys/syscall.h> #include <unistd.h> #include <utils/misc.h> @@ -173,6 +174,12 @@ static void Linux_setenv(JNIEnv* env, jobject, jstring javaName, jstring javaVal throwIfMinusOne(env, "setenv", setenv(name.c_str(), value.c_str(), overwrite ? 1 : 0)); } + +static jint Linux_gettid(JNIEnv* env, jobject) { + // gettid(2() was added in glibc 2.30 but Android uses an older version in prebuilt. + return syscall(__NR_gettid); +} + static void maybeRedirectLog() { auto ravenwoodLogOut = getenv("RAVENWOOD_LOG_OUT"); if (ravenwoodLogOut == NULL) { @@ -207,6 +214,7 @@ static const JNINativeMethod sMethods[] = { "stat", "(Ljava/lang/String;)Landroid/system/StructStat;", (void*)Linux_stat }, { "nOpen", "(Ljava/lang/String;II)I", (void*)Linux_open }, { "setenv", "(Ljava/lang/String;Ljava/lang/String;Z)V", (void*)Linux_setenv }, + { "gettid", "()I", (void*)Linux_gettid }, }; extern "C" jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) { diff --git a/ravenwood/tests/runtime-test/Android.bp b/ravenwood/tests/runtime-test/Android.bp index 410292001670..0c0df1f993aa 100644 --- a/ravenwood/tests/runtime-test/Android.bp +++ b/ravenwood/tests/runtime-test/Android.bp @@ -10,6 +10,9 @@ package { android_ravenwood_test { name: "RavenwoodRuntimeTest", + libs: [ + "ravenwood-helper-runtime", + ], static_libs: [ "androidx.annotation_annotation", "androidx.test.ext.junit", diff --git a/ravenwood/tests/runtime-test/test/com/android/ravenwoodtest/runtimetest/IdentityTest.java b/ravenwood/tests/runtime-test/test/com/android/ravenwoodtest/runtimetest/IdentityTest.java new file mode 100644 index 000000000000..8e04b698c9d9 --- /dev/null +++ b/ravenwood/tests/runtime-test/test/com/android/ravenwoodtest/runtimetest/IdentityTest.java @@ -0,0 +1,66 @@ +/* + * 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.ravenwoodtest.runtimetest; + +import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE; +import static android.os.Process.FIRST_APPLICATION_UID; + +import static org.junit.Assert.assertEquals; + +import android.os.Binder; +import android.os.Build; +import android.os.Process; +import android.platform.test.ravenwood.RavenwoodConfig; +import android.system.Os; + +import com.android.ravenwood.RavenwoodRuntimeState; + +import dalvik.system.VMRuntime; + +import org.junit.Test; + +public class IdentityTest { + + @RavenwoodConfig.Config + public static final RavenwoodConfig sConfig = + new RavenwoodConfig.Builder() + .setTargetSdkLevel(UPSIDE_DOWN_CAKE) + .setProcessApp() + .build(); + + @Test + public void testUid() { + assertEquals(FIRST_APPLICATION_UID, RavenwoodRuntimeState.sUid); + assertEquals(FIRST_APPLICATION_UID, Os.getuid()); + assertEquals(FIRST_APPLICATION_UID, Process.myUid()); + assertEquals(FIRST_APPLICATION_UID, Binder.getCallingUid()); + } + + @Test + public void testPid() { + int pid = RavenwoodRuntimeState.sPid; + assertEquals(pid, Os.getpid()); + assertEquals(pid, Process.myPid()); + assertEquals(pid, Binder.getCallingPid()); + } + + @Test + public void testTargetSdkLevel() { + assertEquals(Build.VERSION_CODES.CUR_DEVELOPMENT, RavenwoodRuntimeState.CUR_DEVELOPMENT); + assertEquals(UPSIDE_DOWN_CAKE, RavenwoodRuntimeState.sTargetSdkLevel); + assertEquals(UPSIDE_DOWN_CAKE, VMRuntime.getRuntime().getTargetSdkVersion()); + } +} diff --git a/ravenwood/tests/runtime-test/test/com/android/ravenwoodtest/runtimetest/OsTest.java b/ravenwood/tests/runtime-test/test/com/android/ravenwoodtest/runtimetest/OsTest.java index c2230c739ccf..c55506a0a10a 100644 --- a/ravenwood/tests/runtime-test/test/com/android/ravenwoodtest/runtimetest/OsTest.java +++ b/ravenwood/tests/runtime-test/test/com/android/ravenwoodtest/runtimetest/OsTest.java @@ -24,6 +24,8 @@ import static android.system.OsConstants.S_ISREG; import static android.system.OsConstants.S_ISSOCK; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertTrue; import static java.nio.file.LinkOption.NOFOLLOW_LINKS; @@ -51,10 +53,12 @@ import java.nio.file.attribute.PosixFileAttributes; import java.nio.file.attribute.PosixFilePermission; import java.util.HashSet; import java.util.Set; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @RunWith(AndroidJUnit4.class) public class OsTest { + public interface ConsumerWithThrow<T> { void accept(T var1) throws Exception; } @@ -165,6 +169,35 @@ public class OsTest { }); } + private static class TestThread extends Thread { + + final CountDownLatch mLatch = new CountDownLatch(1); + int mTid; + + TestThread() { + setDaemon(true); + } + + @Override + public void run() { + mTid = Os.gettid(); + mLatch.countDown(); + } + } + + @Test + public void testGetTid() throws InterruptedException { + var t1 = new TestThread(); + var t2 = new TestThread(); + t1.start(); + t2.start(); + // Wait for thread execution + assertTrue(t1.mLatch.await(1, TimeUnit.SECONDS)); + assertTrue(t2.mLatch.await(1, TimeUnit.SECONDS)); + // Make sure the tid is unique per-thread + assertNotEquals(t1.mTid, t2.mTid); + } + // Verify StructStat values from libcore against native JVM PosixFileAttributes private static void assertAttributesEqual(PosixFileAttributes attr, StructStat stat) { assertEquals(attr.lastModifiedTime(), convertTimespecToFileTime(stat.st_mtim)); diff --git a/ravenwood/tests/runtime-test/test/com/android/ravenwoodtest/runtimetest/ProcessTest.java b/ravenwood/tests/runtime-test/test/com/android/ravenwoodtest/runtimetest/ProcessTest.java new file mode 100644 index 000000000000..d25b5c19f351 --- /dev/null +++ b/ravenwood/tests/runtime-test/test/com/android/ravenwoodtest/runtimetest/ProcessTest.java @@ -0,0 +1,54 @@ +/* + * 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.ravenwoodtest.runtimetest; + +import static android.os.Process.THREAD_PRIORITY_BACKGROUND; +import static android.os.Process.THREAD_PRIORITY_DEFAULT; +import static android.os.Process.THREAD_PRIORITY_FOREGROUND; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThrows; + +import android.os.Process; +import android.system.Os; + +import org.junit.Test; + +public class ProcessTest { + + @Test + public void testGetUidPidTid() { + assertEquals(Os.getuid(), Process.myUid()); + assertEquals(Os.getpid(), Process.myPid()); + assertEquals(Os.gettid(), Process.myTid()); + } + + @Test + public void testThreadPriority() { + assertThrows(UnsupportedOperationException.class, + () -> Process.getThreadPriority(Process.myTid() + 1)); + assertThrows(UnsupportedOperationException.class, + () -> Process.setThreadPriority(Process.myTid() + 1, THREAD_PRIORITY_DEFAULT)); + assertEquals(THREAD_PRIORITY_DEFAULT, Process.getThreadPriority(Process.myTid())); + Process.setThreadPriority(THREAD_PRIORITY_FOREGROUND); + assertEquals(THREAD_PRIORITY_FOREGROUND, Process.getThreadPriority(Process.myTid())); + Process.setCanSelfBackground(false); + Process.setThreadPriority(THREAD_PRIORITY_DEFAULT); + assertEquals(THREAD_PRIORITY_DEFAULT, Process.getThreadPriority(Process.myTid())); + assertThrows(IllegalArgumentException.class, + () -> Process.setThreadPriority(THREAD_PRIORITY_BACKGROUND)); + } +} |