Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2037)

Unified Diff: content/shell/android/browsertests_apk/src/org/chromium/content_browsertests_apk/BrowserTestSystemMessageHandler.java

Issue 12213021: Android content_browsertests: Allow processing java tasks in nested mode. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/shell/android/browsertests_apk/src/org/chromium/content_browsertests_apk/BrowserTestSystemMessageHandler.java
diff --git a/content/shell/android/browsertests_apk/src/org/chromium/content_browsertests_apk/BrowserTestSystemMessageHandler.java b/content/shell/android/browsertests_apk/src/org/chromium/content_browsertests_apk/BrowserTestSystemMessageHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..2ba7e9435c86bc67615bda67095797f6d32b4551
--- /dev/null
+++ b/content/shell/android/browsertests_apk/src/org/chromium/content_browsertests_apk/BrowserTestSystemMessageHandler.java
@@ -0,0 +1,128 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.content_browsertests_apk;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.MessageQueue;
+import android.util.Log;
+
+import org.chromium.base.CalledByNative;
+import org.chromium.base.JNINamespace;
+import java.lang.reflect.Method;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+
+/**
+ * Handles processing messages in nested run loops.
+ *
+ * Android does not support nested message loops by default. While running
+ * in nested mode, we use reflection to retreive messages from the MessageQueue
+ * and dispatch them.
+ */
+@JNINamespace("content")
+class BrowserTestSystemMessageHandler {
+ // See org.chromium.base.SystemMessageHandler for more message ids.
+ // The id here should not conflict with the ones in SystemMessageHandler.
+ private static final int QUIT_MESSAGE = 10;
+ private static final Handler mHandler = new Handler();
+
+ private BrowserTestSystemMessageHandler() {
+ }
+
+ /**
+ * Processes messages from the current MessageQueue till the queue becomes idle.
+ */
+ @SuppressWarnings("unused")
+ @CalledByNative
+ private boolean runNestedLoopTillIdle() {
+ boolean quitLoop = false;
+
+ MessageQueue queue = Looper.myQueue();
+ queue.addIdleHandler(new MessageQueue.IdleHandler() {
+ @Override
+ public boolean queueIdle() {
+ mHandler.sendMessage(mHandler.obtainMessage(QUIT_MESSAGE));
+ return false;
+ }
+ });
+
+ Class<?> messageQueueClazz = queue.getClass();
+ Method nextMethod = null;
+ try {
+ nextMethod = messageQueueClazz.getDeclaredMethod("next");
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ return false;
+ } catch (NoSuchMethodException e) {
+ e.printStackTrace();
+ return false;
+ }
+ nextMethod.setAccessible(true);
+
+ while (!quitLoop) {
+ Message msg = null;
+ try {
+ msg = (Message)nextMethod.invoke(queue);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ return false;
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ return false;
+ } catch (InvocationTargetException e) {
+ e.printStackTrace();
+ return false;
+ }
+
+ if (msg != null) {
+ if (msg.what == QUIT_MESSAGE) {
+ quitLoop = true;
+ }
+ Class messageClazz = msg.getClass();
+ Field targetFiled = null;
+ try {
+ targetFiled = messageClazz.getDeclaredField("target");
+ } catch (SecurityException e) {
+ e.printStackTrace();
+ return false;
+ } catch (NoSuchFieldException e) {
+ e.printStackTrace();
+ return false;
+ }
+ targetFiled.setAccessible(true);
+
+ Handler target = null;
+ try {
+ target = (Handler) targetFiled.get(msg);
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ return false;
+ } catch (IllegalAccessException e) {
+ e.printStackTrace();
+ return false;
+ }
+
+ if (target == null) {
+ // No target is a magic identifier for the quit message.
+ quitLoop = true;
+ }
+
+ target.dispatchMessage(msg);
+ msg.recycle();
+ } else {
+ quitLoop = true;
+ }
+ }
+ return true;
+ }
+
+ @SuppressWarnings("unused")
+ @CalledByNative
+ private static BrowserTestSystemMessageHandler create() {
+ return new BrowserTestSystemMessageHandler();
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698