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

Commit 1c7db6b9 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Support Handler/Looper for Ravenwood, with CTS.

Now that we have a solid foundation of classes available, one of the
tricker pieces is supporting Handler/Looper under Ravenwood.  At its
core, the native implementation of MessageQueue can be emulated using
core JVM primitives, which is enough to reliably pass CTS.

Advanced features like FileDescriptor events will need to wait until
we eventually have real JNI support.

Fix obscure bug with SystemClock; must be positive number.  Always
start our "fake" pointers from 1 to prevent `nullptr` oddness.

Bug: 292141694
Test: atest-dev CtsOsTestCasesRavenwood CtsOsTestCases
Change-Id: I0f82b659973443968ef2609a7e3151f381abff29
parent c914beed
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -63,6 +63,7 @@ import java.lang.reflect.Modifier;
 * your new thread.  The given Runnable or Message will then be scheduled
 * your new thread.  The given Runnable or Message will then be scheduled
 * in the Handler's message queue and processed when appropriate.
 * in the Handler's message queue and processed when appropriate.
 */
 */
@android.ravenwood.annotation.RavenwoodKeepWholeClass
public class Handler {
public class Handler {
    /*
    /*
     * Set this flag to true to detect anonymous, local or member classes
     * Set this flag to true to detect anonymous, local or member classes
+1 −0
Original line number Original line Diff line number Diff line
@@ -25,6 +25,7 @@ import android.annotation.Nullable;
 * <p>
 * <p>
 * Note that just like with a regular {@link Thread}, {@link #start()} must still be called.
 * Note that just like with a regular {@link Thread}, {@link #start()} must still be called.
 */
 */
@android.ravenwood.annotation.RavenwoodKeepWholeClass
public class HandlerThread extends Thread {
public class HandlerThread extends Thread {
    int mPriority;
    int mPriority;
    int mTid = -1;
    int mTid = -1;
+40 −5
Original line number Original line Diff line number Diff line
@@ -24,6 +24,8 @@ import android.util.Printer;
import android.util.Slog;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoOutputStream;


import java.util.Objects;

/**
/**
  * Class used to run a message loop for a thread.  Threads by default do
  * Class used to run a message loop for a thread.  Threads by default do
  * not have a message loop associated with them; to create one, call
  * not have a message loop associated with them; to create one, call
@@ -54,6 +56,7 @@ import android.util.proto.ProtoOutputStream;
  *      }
  *      }
  *  }</pre>
  *  }</pre>
  */
  */
@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class Looper {
public final class Looper {
    /*
    /*
     * API Implementation Note:
     * API Implementation Note:
@@ -143,6 +146,30 @@ public final class Looper {
        }
        }
    }
    }


    /**
     * Force the application's main looper to the given value.  The main looper is typically
     * configured automatically by the OS, so this capability is only intended to enable testing.
     *
     * @hide
     */
    public static void setMainLooperForTest(@NonNull Looper looper) {
        synchronized (Looper.class) {
            sMainLooper = Objects.requireNonNull(looper);
        }
    }

    /**
     * Clear the application's main looper to be undefined.  The main looper is typically
     * configured automatically by the OS, so this capability is only intended to enable testing.
     *
     * @hide
     */
    public static void clearMainLooperForTest() {
        synchronized (Looper.class) {
            sMainLooper = null;
        }
    }

    /**
    /**
     * Set the transaction observer for all Loopers in this process.
     * Set the transaction observer for all Loopers in this process.
     *
     *
@@ -282,11 +309,7 @@ public final class Looper {


        // Allow overriding a threshold with a system prop. e.g.
        // Allow overriding a threshold with a system prop. e.g.
        // adb shell 'setprop log.looper.1000.main.slow 1 && stop && start'
        // adb shell 'setprop log.looper.1000.main.slow 1 && stop && start'
        final int thresholdOverride =
        final int thresholdOverride = getThresholdOverride();
                SystemProperties.getInt("log.looper."
                        + Process.myUid() + "."
                        + Thread.currentThread().getName()
                        + ".slow", -1);


        me.mSlowDeliveryDetected = false;
        me.mSlowDeliveryDetected = false;


@@ -297,6 +320,18 @@ public final class Looper {
        }
        }
    }
    }


    @android.ravenwood.annotation.RavenwoodReplace
    private static int getThresholdOverride() {
        return SystemProperties.getInt("log.looper."
                + Process.myUid() + "."
                + Thread.currentThread().getName()
                + ".slow", -1);
    }

    private static int getThresholdOverride$ravenwood() {
        return -1;
    }

    private static boolean showSlowLog(long threshold, long measureStart, long measureEnd,
    private static boolean showSlowLog(long threshold, long measureStart, long measureEnd,
            String what, Message msg) {
            String what, Message msg) {
        final long actualTime = measureEnd - measureStart;
        final long actualTime = measureEnd - measureStart;
+1 −0
Original line number Original line Diff line number Diff line
@@ -33,6 +33,7 @@ import com.android.internal.annotations.VisibleForTesting;
 * {@link Handler#obtainMessage Handler.obtainMessage()} methods, which will pull
 * {@link Handler#obtainMessage Handler.obtainMessage()} methods, which will pull
 * them from a pool of recycled objects.</p>
 * them from a pool of recycled objects.</p>
 */
 */
@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class Message implements Parcelable {
public final class Message implements Parcelable {
    /**
    /**
     * User-defined message code so that the recipient can identify
     * User-defined message code so that the recipient can identify
+6 −0
Original line number Original line Diff line number Diff line
@@ -40,6 +40,9 @@ import java.util.ArrayList;
 * <p>You can retrieve the MessageQueue for the current thread with
 * <p>You can retrieve the MessageQueue for the current thread with
 * {@link Looper#myQueue() Looper.myQueue()}.
 * {@link Looper#myQueue() Looper.myQueue()}.
 */
 */
@android.ravenwood.annotation.RavenwoodKeepWholeClass
@android.ravenwood.annotation.RavenwoodNativeSubstitutionClass(
        "com.android.hoststubgen.nativesubstitution.MessageQueue_host")
public final class MessageQueue {
public final class MessageQueue {
    private static final String TAG = "MessageQueue";
    private static final String TAG = "MessageQueue";
    private static final boolean DEBUG = false;
    private static final boolean DEBUG = false;
@@ -194,6 +197,7 @@ public final class MessageQueue {
     * @see OnFileDescriptorEventListener
     * @see OnFileDescriptorEventListener
     * @see #removeOnFileDescriptorEventListener
     * @see #removeOnFileDescriptorEventListener
     */
     */
    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
    public void addOnFileDescriptorEventListener(@NonNull FileDescriptor fd,
    public void addOnFileDescriptorEventListener(@NonNull FileDescriptor fd,
            @OnFileDescriptorEventListener.Events int events,
            @OnFileDescriptorEventListener.Events int events,
            @NonNull OnFileDescriptorEventListener listener) {
            @NonNull OnFileDescriptorEventListener listener) {
@@ -221,6 +225,7 @@ public final class MessageQueue {
     * @see OnFileDescriptorEventListener
     * @see OnFileDescriptorEventListener
     * @see #addOnFileDescriptorEventListener
     * @see #addOnFileDescriptorEventListener
     */
     */
    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
    public void removeOnFileDescriptorEventListener(@NonNull FileDescriptor fd) {
    public void removeOnFileDescriptorEventListener(@NonNull FileDescriptor fd) {
        if (fd == null) {
        if (fd == null) {
            throw new IllegalArgumentException("fd must not be null");
            throw new IllegalArgumentException("fd must not be null");
@@ -231,6 +236,7 @@ public final class MessageQueue {
        }
        }
    }
    }


    @android.ravenwood.annotation.RavenwoodThrow(blockedBy = android.os.ParcelFileDescriptor.class)
    private void updateOnFileDescriptorEventListenerLocked(FileDescriptor fd, int events,
    private void updateOnFileDescriptorEventListenerLocked(FileDescriptor fd, int events,
            OnFileDescriptorEventListener listener) {
            OnFileDescriptorEventListener listener) {
        final int fdNum = fd.getInt$();
        final int fdNum = fd.getInt$();
Loading