Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5e210d7d authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Initial Process and Binder support, with CTS.

The Ravenwood environment doesn't support IPC, but much of the code
that developers intend to test (such as AIDL stubs) still relies on
baseline same-process behavior to be intact.

This change adds UID and PID support to Process and Binder, but we
carefully communicate that it's only available when the test author
has configured it via a RavenwoodRule.  This ensures that tests
don't accidentally rely on unexpected defaults, as some tests will
want AID_SYSTEM, and others want a normal app UID.

Also bring along SystemClock, PatternMatcher, and ParcelUuid
along with relevant tests.

Finally, now that we have an IgnoreUnderRavenwood annotation, we
can pivot back our default failure to be a RuntimeException instead
of an AssumptionViolatedException.

Bug: 292141694
Test: atest-dev CtsOsTestCasesRavenwood CtsOsTestCases
Change-Id: I5f54c3179b2d305b9ab9144c43fd063c6b756e44
parent 55c2256e
Loading
Loading
Loading
Loading
+96 −0
Original line number Diff line number Diff line
@@ -30,9 +30,11 @@ import com.android.internal.os.BinderCallHeavyHitterWatcher;
import com.android.internal.os.BinderCallHeavyHitterWatcher.BinderCallHeavyHitterListener;
import com.android.internal.os.BinderInternal;
import com.android.internal.os.BinderInternal.CallSession;
import com.android.internal.os.SomeArgs;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
import com.android.internal.util.FunctionalUtils.ThrowingSupplier;
import com.android.internal.util.Preconditions;

import dalvik.annotation.optimization.CriticalNative;

@@ -46,6 +48,7 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Modifier;
import java.util.concurrent.atomic.AtomicReferenceArray;
import java.util.function.Supplier;

/**
 * Base class for a remotable object, the core part of a lightweight
@@ -289,6 +292,33 @@ public class Binder implements IBinder {
        sWarnOnBlockingOnCurrentThread.set(sWarnOnBlocking);
    }

    private static ThreadLocal<SomeArgs> sIdentity$ravenwood;

    @android.ravenwood.annotation.RavenwoodKeepWholeClass
    private static class IdentitySupplier implements Supplier<SomeArgs> {
        @Override
        public SomeArgs get() {
            final SomeArgs args = SomeArgs.obtain();
            // Match IPCThreadState behavior
            args.arg1 = Boolean.FALSE;
            args.argi1 = android.os.Process.myUid();
            args.argi2 = android.os.Process.myPid();
            return args;
        }
    }

    /** @hide */
    @android.ravenwood.annotation.RavenwoodKeep
    public static void init$ravenwood() {
        sIdentity$ravenwood = ThreadLocal.withInitial(new IdentitySupplier());
    }

    /** @hide */
    @android.ravenwood.annotation.RavenwoodKeep
    public static void reset$ravenwood() {
        sIdentity$ravenwood = null;
    }

    /**
     * Raw native pointer to JavaBBinderHolder object. Owned by this Java object. Not null.
     */
@@ -312,8 +342,14 @@ public class Binder implements IBinder {
     * Warning: oneway transactions do not receive PID.
     */
    @CriticalNative
    @android.ravenwood.annotation.RavenwoodReplace
    public static final native int getCallingPid();

    /** @hide */
    public static final int getCallingPid$ravenwood() {
        return Preconditions.requireNonNullViaRavenwoodRule(sIdentity$ravenwood).get().argi2;
    }

    /**
     * Return the Linux UID assigned to the process that sent you the
     * current transaction that is being processed. This UID can be used with
@@ -322,8 +358,14 @@ public class Binder implements IBinder {
     * incoming transaction, then its own UID is returned.
     */
    @CriticalNative
    @android.ravenwood.annotation.RavenwoodReplace
    public static final native int getCallingUid();

    /** @hide */
    public static final int getCallingUid$ravenwood() {
        return Preconditions.requireNonNullViaRavenwoodRule(sIdentity$ravenwood).get().argi1;
    }

    /**
     * Returns {@code true} if the current thread is currently executing an
     * incoming transaction.
@@ -331,6 +373,7 @@ public class Binder implements IBinder {
     * @hide
     */
    @CriticalNative
    @android.ravenwood.annotation.RavenwoodReplace
    public static final native boolean isDirectlyHandlingTransactionNative();

    /** @hide */
@@ -344,6 +387,7 @@ public class Binder implements IBinder {
    /**
     * @hide
     */
    @android.ravenwood.annotation.RavenwoodKeep
    public static final boolean isDirectlyHandlingTransaction() {
        return sIsHandlingBinderTransaction || isDirectlyHandlingTransactionNative();
    }
@@ -363,8 +407,15 @@ public class Binder implements IBinder {
    * @hide
    */
    @CriticalNative
    @android.ravenwood.annotation.RavenwoodReplace
    private static native boolean hasExplicitIdentity();

    /** @hide */
    private static boolean hasExplicitIdentity$ravenwood() {
        return Preconditions.requireNonNullViaRavenwoodRule(sIdentity$ravenwood).get().arg1
                == Boolean.TRUE;
    }

    /**
     * Return the Linux UID assigned to the process that sent the transaction
     * currently being processed.
@@ -373,6 +424,7 @@ public class Binder implements IBinder {
     * executing an incoming transaction and the calling identity has not been
     * explicitly set with {@link #clearCallingIdentity()}
     */
    @android.ravenwood.annotation.RavenwoodKeep
    public static final int getCallingUidOrThrow() {
        if (!isDirectlyHandlingTransaction() && !hasExplicitIdentity()) {
            throw new IllegalStateException(
@@ -434,8 +486,26 @@ public class Binder implements IBinder {
     * @see #restoreCallingIdentity(long)
     */
    @CriticalNative
    @android.ravenwood.annotation.RavenwoodReplace
    public static final native long clearCallingIdentity();

    /** @hide */
    public static final long clearCallingIdentity$ravenwood() {
        final SomeArgs args = Preconditions.requireNonNullViaRavenwoodRule(
                sIdentity$ravenwood).get();
        long res = ((long) args.argi1 << 32) | args.argi2;
        if (args.arg1 == Boolean.TRUE) {
            res |= (0x1 << 30);
        } else {
            res &= ~(0x1 << 30);
        }
        // Match IPCThreadState behavior
        args.arg1 = Boolean.TRUE;
        args.argi1 = android.os.Process.myUid();
        args.argi2 = android.os.Process.myPid();
        return res;
    }

    /**
     * Restore the identity of the incoming IPC on the current thread
     * back to a previously identity that was returned by {@link
@@ -447,8 +517,18 @@ public class Binder implements IBinder {
     * @see #clearCallingIdentity
     */
    @CriticalNative
    @android.ravenwood.annotation.RavenwoodReplace
    public static final native void restoreCallingIdentity(long token);

    /** @hide */
    public static final void restoreCallingIdentity$ravenwood(long token) {
        final SomeArgs args = Preconditions.requireNonNullViaRavenwoodRule(
                sIdentity$ravenwood).get();
        args.arg1 = ((token & (0x1 << 30)) != 0) ? Boolean.TRUE : Boolean.FALSE;
        args.argi1 = (int) (token >> 32);
        args.argi2 = (int) (token & ~(0x1 << 30));
    }

    /**
     * Convenience method for running the provided action enclosed in
     * {@link #clearCallingIdentity}/{@link #restoreCallingIdentity}.
@@ -644,8 +724,14 @@ public class Binder implements IBinder {
     * in order to prevent the process from holding on to objects longer than
     * it needs to.
     */
    @android.ravenwood.annotation.RavenwoodReplace
    public static final native void flushPendingCommands();

    /** @hide */
    public static final void flushPendingCommands$ravenwood() {
        // Ravenwood doesn't support IPC; ignored
    }

    /**
     * Add the calling thread to the IPC thread pool. This function does
     * not return until the current process is exiting.
@@ -703,6 +789,7 @@ public class Binder implements IBinder {
     * <p>If you're creating a Binder token (a Binder object without an attached interface),
     * you should use {@link #Binder(String)} instead.
     */
    @android.ravenwood.annotation.RavenwoodKeep
    public Binder() {
        this(null);
    }
@@ -719,6 +806,7 @@ public class Binder implements IBinder {
     * Instead of creating multiple tokens with the same descriptor, consider adding a suffix to
     * help identify them.
     */
    @android.ravenwood.annotation.RavenwoodKeep
    public Binder(@Nullable String descriptor) {
        mObject = getNativeBBinderHolder();
        if (mObject != 0L) {
@@ -742,6 +830,7 @@ public class Binder implements IBinder {
     * will be implemented for you to return the given owner IInterface when
     * the corresponding descriptor is requested.
     */
    @android.ravenwood.annotation.RavenwoodKeep
    public void attachInterface(@Nullable IInterface owner, @Nullable String descriptor) {
        mOwner = owner;
        mDescriptor = descriptor;
@@ -750,6 +839,7 @@ public class Binder implements IBinder {
    /**
     * Default implementation returns an empty interface name.
     */
    @android.ravenwood.annotation.RavenwoodKeep
    public @Nullable String getInterfaceDescriptor() {
        return mDescriptor;
    }
@@ -758,6 +848,7 @@ public class Binder implements IBinder {
     * Default implementation always returns true -- if you got here,
     * the object is alive.
     */
    @android.ravenwood.annotation.RavenwoodKeep
    public boolean pingBinder() {
        return true;
    }
@@ -768,6 +859,7 @@ public class Binder implements IBinder {
     * Note that if you're calling on a local binder, this always returns true
     * because your process is alive if you're calling it.
     */
    @android.ravenwood.annotation.RavenwoodKeep
    public boolean isBinderAlive() {
        return true;
    }
@@ -777,6 +869,7 @@ public class Binder implements IBinder {
     * to return the associated {@link IInterface} if it matches the requested
     * descriptor.
     */
    @android.ravenwood.annotation.RavenwoodKeep
    public @Nullable IInterface queryLocalInterface(@NonNull String descriptor) {
        if (mDescriptor != null && mDescriptor.equals(descriptor)) {
            return mOwner;
@@ -1250,12 +1343,14 @@ public class Binder implements IBinder {
    /**
     * Local implementation is a no-op.
     */
    @android.ravenwood.annotation.RavenwoodKeep
    public void linkToDeath(@NonNull DeathRecipient recipient, int flags) {
    }

    /**
     * Local implementation is a no-op.
     */
    @android.ravenwood.annotation.RavenwoodKeep
    public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags) {
        return true;
    }
@@ -1283,6 +1378,7 @@ public class Binder implements IBinder {
        }
    }

    @android.ravenwood.annotation.RavenwoodReplace
    private static native long getNativeBBinderHolder();

    private static long getNativeBBinderHolder$ravenwood() {
+1 −0
Original line number Diff line number Diff line
@@ -194,6 +194,7 @@ public interface IBinder {
     * Limit that should be placed on IPC sizes, in bytes, to keep them safely under the transaction
     * buffer limit.
     */
    @android.ravenwood.annotation.RavenwoodKeep
    static int getSuggestedMaxIpcSizeBytes() {
        return MAX_IPC_SIZE;
    }
+32 −0
Original line number Diff line number Diff line
@@ -34,6 +34,9 @@ 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 dalvik.system.VMRuntime;

import libcore.io.IoUtils;
@@ -833,14 +836,37 @@ public class Process {
        return VMRuntime.getRuntime().is64Bit();
    }

    private static SomeArgs sIdentity$ravenwood;

    /** @hide */
    @android.ravenwood.annotation.RavenwoodKeep
    public static void init$ravenwood(int uid, int pid) {
        final SomeArgs args = SomeArgs.obtain();
        args.argi1 = uid;
        args.argi2 = pid;
        sIdentity$ravenwood = 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
    public static final int myPid() {
        return Os.getpid();
    }

    /** @hide */
    public static final int myPid$ravenwood() {
        return Preconditions.requireNonNullViaRavenwoodRule(sIdentity$ravenwood).argi2;
    }

    /**
     * Returns the identifier of this process' parent.
     * @hide
@@ -864,10 +890,16 @@ public class Process {
     * 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
    public static final int myUid() {
        return Os.getuid();
    }

    /** @hide */
    public static final int myUid$ravenwood() {
        return Preconditions.requireNonNullViaRavenwoodRule(sIdentity$ravenwood).argi1;
    }

    /**
     * Returns this process's user handle.  This is the
     * user the process is running under.  It is distinct from
+39 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.location.ILocationManager;
import android.location.LocationTime;
import android.text.format.DateUtils;
import android.util.Slog;

import dalvik.annotation.optimization.CriticalNative;
@@ -125,6 +126,7 @@ public final class SystemClock {
     *
     * @param ms to sleep before returning, in milliseconds of uptime.
     */
    @android.ravenwood.annotation.RavenwoodKeep
    public static void sleep(long ms)
    {
        long start = uptimeMillis();
@@ -186,8 +188,16 @@ public final class SystemClock {
     * @return milliseconds of non-sleep uptime since boot.
     */
    @CriticalNative
    @android.ravenwood.annotation.RavenwoodReplace
    native public static long uptimeMillis();

    /** @hide */
    public static long uptimeMillis$ravenwood() {
        // Ravenwood booted in Jan 2023, and has been in deep sleep for one week
        return System.currentTimeMillis() - (1672556400L * 1_000)
                - (DateUtils.WEEK_IN_MILLIS * 1_000);
    }

    /**
     * Returns nanoseconds since boot, not counting time spent in deep sleep.
     *
@@ -195,8 +205,16 @@ public final class SystemClock {
     * @hide
     */
    @CriticalNative
    @android.ravenwood.annotation.RavenwoodReplace
    public static native long uptimeNanos();

    /** @hide */
    public static long uptimeNanos$ravenwood() {
        // Ravenwood booted in Jan 2023, and has been in deep sleep for one week
        return System.nanoTime() - (1672556400L * 1_000_000_000)
                - (DateUtils.WEEK_IN_MILLIS * 1_000_000_000);
    }

    /**
     * Return {@link Clock} that starts at system boot, not counting time spent
     * in deep sleep.
@@ -218,8 +236,15 @@ public final class SystemClock {
     * @return elapsed milliseconds since boot.
     */
    @CriticalNative
    @android.ravenwood.annotation.RavenwoodReplace
    native public static long elapsedRealtime();

    /** @hide */
    public static long elapsedRealtime$ravenwood() {
        // Ravenwood booted in Jan 2023, and has been in deep sleep for one week
        return System.currentTimeMillis() - (1672556400L * 1_000);
    }

    /**
     * Return {@link Clock} that starts at system boot, including time spent in
     * sleep.
@@ -241,8 +266,15 @@ public final class SystemClock {
     * @return elapsed nanoseconds since boot.
     */
    @CriticalNative
    @android.ravenwood.annotation.RavenwoodReplace
    public static native long elapsedRealtimeNanos();

    /** @hide */
    public static long elapsedRealtimeNanos$ravenwood() {
        // Ravenwood booted in Jan 2023, and has been in deep sleep for one week
        return System.nanoTime() - (1672556400L * 1_000_000_000);
    }

    /**
     * Returns milliseconds running in the current thread.
     *
@@ -271,8 +303,15 @@ public final class SystemClock {
     */
    @UnsupportedAppUsage
    @CriticalNative
    @android.ravenwood.annotation.RavenwoodReplace
    public static native long currentTimeMicro();

    /** @hide */
    public static long currentTimeMicro$ravenwood() {
        // Ravenwood booted in Jan 2023, and has been in deep sleep for one week
        return System.nanoTime() / 1000L;
    }

    /**
     * Returns milliseconds since January 1, 1970 00:00:00.0 UTC, synchronized
     * using a remote network source outside the device.
+1 −2
Original line number Diff line number Diff line
@@ -28,9 +28,8 @@ java_library {
    name: "ravenwood-junit",
    srcs: ["junit-src/**/*.java"],
    libs: [
        "framework-minus-apex.ravenwood",
        "junit",
    ],
    sdk_version: "core_current",
    host_supported: true,
    visibility: ["//visibility:public"],
}
Loading