Loading core/java/android/os/CombinedMessageQueue/MessageQueue.java +35 −31 Original line number Diff line number Diff line Loading @@ -19,8 +19,6 @@ package android.os; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.TestApi; import android.app.ActivityThread; import android.app.Instrumentation; import android.compat.annotation.UnsupportedAppUsage; import android.os.Process; import android.os.UserHandle; Loading Loading @@ -88,14 +86,20 @@ public final class MessageQueue { // queue for async messages when inserting a message at the tail. private int mAsyncMessageCount; /* /** * Select between two implementations of message queue. The legacy implementation is used * by default as it provides maximum compatibility with applications and tests that * reach into MessageQueue via the mMessages field. The concurrent implemmentation is used for * system processes and provides a higher level of concurrency and higher enqueue throughput * than the legacy implementation. */ private boolean mUseConcurrent; private final boolean mUseConcurrent; /** * Caches process-level checks that determine `mUseConcurrent`. * This is to avoid redoing checks that shouldn't change during the process's lifetime. */ private static Boolean sIsProcessAllowedToUseConcurrent = null; @RavenwoodRedirect private native static long nativeInit(); Loading @@ -112,37 +116,37 @@ public final class MessageQueue { private native static void nativeSetFileDescriptorEvents(long ptr, int fd, int events); MessageQueue(boolean quitAllowed) { // Concurrent mode modifies behavior that is observable via reflection and is commonly used // by tests. if (sIsProcessAllowedToUseConcurrent == null) { // Concurrent mode modifies behavior that is observable via reflection and is commonly // used by tests. // For now, we limit it to system processes to avoid breaking apps and their tests. mUseConcurrent = UserHandle.isCore(Process.myUid()); // Even then, we don't use it if instrumentation is loaded as it breaks some // platform tests. final Instrumentation instrumentation = getInstrumentation(); mUseConcurrent &= instrumentation == null || !instrumentation.isInstrumenting(); // We can lift this restriction in the future after we've made it possible for test authors // to test Looper and MessageQueue without resorting to reflection. boolean useConcurrent = UserHandle.isCore(Process.myUid()); // Holdback study. if (mUseConcurrent && Flags.messageQueueForceLegacy()) { mUseConcurrent = false; // Some platform tests run in system UIDs. // Use this awful heuristic to detect them. if (useConcurrent) { final String processName = Process.myProcessName(); if (processName.contains("test") || processName.contains("Test")) { useConcurrent = false; } mQuitAllowed = quitAllowed; mPtr = nativeInit(); } @android.ravenwood.annotation.RavenwoodReplace(blockedBy = ActivityThread.class) private static Instrumentation getInstrumentation() { final ActivityThread activityThread = ActivityThread.currentActivityThread(); if (activityThread != null) { return activityThread.getInstrumentation(); // We can lift this restriction in the future after we've made it possible for test // authors to test Looper and MessageQueue without resorting to reflection. // Holdback study. if (useConcurrent && Flags.messageQueueForceLegacy()) { useConcurrent = false; } return null; sIsProcessAllowedToUseConcurrent = useConcurrent; mUseConcurrent = useConcurrent; } else { mUseConcurrent = sIsProcessAllowedToUseConcurrent; } private static Instrumentation getInstrumentation$ravenwood() { return null; // Instrumentation not supported on Ravenwood yet. mQuitAllowed = quitAllowed; mPtr = nativeInit(); } @Override Loading Loading
core/java/android/os/CombinedMessageQueue/MessageQueue.java +35 −31 Original line number Diff line number Diff line Loading @@ -19,8 +19,6 @@ package android.os; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.TestApi; import android.app.ActivityThread; import android.app.Instrumentation; import android.compat.annotation.UnsupportedAppUsage; import android.os.Process; import android.os.UserHandle; Loading Loading @@ -88,14 +86,20 @@ public final class MessageQueue { // queue for async messages when inserting a message at the tail. private int mAsyncMessageCount; /* /** * Select between two implementations of message queue. The legacy implementation is used * by default as it provides maximum compatibility with applications and tests that * reach into MessageQueue via the mMessages field. The concurrent implemmentation is used for * system processes and provides a higher level of concurrency and higher enqueue throughput * than the legacy implementation. */ private boolean mUseConcurrent; private final boolean mUseConcurrent; /** * Caches process-level checks that determine `mUseConcurrent`. * This is to avoid redoing checks that shouldn't change during the process's lifetime. */ private static Boolean sIsProcessAllowedToUseConcurrent = null; @RavenwoodRedirect private native static long nativeInit(); Loading @@ -112,37 +116,37 @@ public final class MessageQueue { private native static void nativeSetFileDescriptorEvents(long ptr, int fd, int events); MessageQueue(boolean quitAllowed) { // Concurrent mode modifies behavior that is observable via reflection and is commonly used // by tests. if (sIsProcessAllowedToUseConcurrent == null) { // Concurrent mode modifies behavior that is observable via reflection and is commonly // used by tests. // For now, we limit it to system processes to avoid breaking apps and their tests. mUseConcurrent = UserHandle.isCore(Process.myUid()); // Even then, we don't use it if instrumentation is loaded as it breaks some // platform tests. final Instrumentation instrumentation = getInstrumentation(); mUseConcurrent &= instrumentation == null || !instrumentation.isInstrumenting(); // We can lift this restriction in the future after we've made it possible for test authors // to test Looper and MessageQueue without resorting to reflection. boolean useConcurrent = UserHandle.isCore(Process.myUid()); // Holdback study. if (mUseConcurrent && Flags.messageQueueForceLegacy()) { mUseConcurrent = false; // Some platform tests run in system UIDs. // Use this awful heuristic to detect them. if (useConcurrent) { final String processName = Process.myProcessName(); if (processName.contains("test") || processName.contains("Test")) { useConcurrent = false; } mQuitAllowed = quitAllowed; mPtr = nativeInit(); } @android.ravenwood.annotation.RavenwoodReplace(blockedBy = ActivityThread.class) private static Instrumentation getInstrumentation() { final ActivityThread activityThread = ActivityThread.currentActivityThread(); if (activityThread != null) { return activityThread.getInstrumentation(); // We can lift this restriction in the future after we've made it possible for test // authors to test Looper and MessageQueue without resorting to reflection. // Holdback study. if (useConcurrent && Flags.messageQueueForceLegacy()) { useConcurrent = false; } return null; sIsProcessAllowedToUseConcurrent = useConcurrent; mUseConcurrent = useConcurrent; } else { mUseConcurrent = sIsProcessAllowedToUseConcurrent; } private static Instrumentation getInstrumentation$ravenwood() { return null; // Instrumentation not supported on Ravenwood yet. mQuitAllowed = quitAllowed; mPtr = nativeInit(); } @Override Loading