1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.content_public.browser.test; 6 7 import android.os.Handler; 8 9 import org.chromium.base.annotations.CalledByNative; 10 import org.chromium.base.annotations.JNINamespace; 11 import org.chromium.base.test.util.LooperUtils; 12 13 import java.lang.reflect.InvocationTargetException; 14 15 /** 16 * Handles processing messages in nested run loops. 17 * 18 * Android does not support nested run loops by default. While running 19 * in nested mode, we use reflection to retreive messages from the MessageQueue 20 * and dispatch them. 21 */ 22 @JNINamespace("content") 23 public class NestedSystemMessageHandler { 24 private static final int QUIT_MESSAGE = 10; 25 private static final Handler sHandler = new Handler(); 26 NestedSystemMessageHandler()27 private NestedSystemMessageHandler() {} 28 29 /** 30 * Dispatches the first message from the current MessageQueue, blocking 31 * until a task becomes available if the queue is empty. Callbacks for 32 * other event handlers registered to the thread's looper (e.g., 33 * MessagePumpAndroid) may also be processed as a side-effect. 34 * 35 * Returns true if task dispatching succeeded, or false if an exception was 36 * thrown. 37 */ 38 @SuppressWarnings("unused") 39 @CalledByNative dispatchOneMessage()40 private static boolean dispatchOneMessage() { 41 try { 42 LooperUtils.runSingleNestedLooperTask(); 43 } catch (IllegalArgumentException | IllegalAccessException | SecurityException 44 | InvocationTargetException e) { 45 e.printStackTrace(); 46 return false; 47 } 48 return true; 49 } 50 51 /* 52 * Causes a previous call to dispatchOneMessage() to stop blocking and 53 * return. 54 */ 55 @SuppressWarnings("unused") 56 @CalledByNative postQuitMessage()57 private static void postQuitMessage() { 58 // Causes MessageQueue.next() to return in case it was blocking waiting 59 // for more messages. 60 sHandler.sendMessage(sHandler.obtainMessage(QUIT_MESSAGE)); 61 } 62 } 63