• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium Authors
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.base.test.task;
6 
7 import android.os.Handler;
8 import android.os.HandlerThread;
9 import android.os.Looper;
10 
11 import org.chromium.base.task.TaskRunner;
12 
13 import java.util.List;
14 import java.util.concurrent.atomic.AtomicBoolean;
15 
16 /** Collection of helpers for testing the java PostTask. */
17 public class SchedulerTestHelpers {
postRecordOrderTask( TaskRunner taskQueue, List<Integer> orderList, int order)18     public static void postRecordOrderTask(
19             TaskRunner taskQueue, List<Integer> orderList, int order) {
20         postRecordOrderDelayedTask(taskQueue, orderList, order, 0);
21     }
22 
postRecordOrderDelayedTask( TaskRunner taskQueue, List<Integer> orderList, int order, long delay)23     public static void postRecordOrderDelayedTask(
24             TaskRunner taskQueue, List<Integer> orderList, int order, long delay) {
25         taskQueue.postDelayedTask(() -> orderList.add(order), delay);
26     }
27 
postTaskAndBlockUntilRun(TaskRunner taskQueue)28     public static void postTaskAndBlockUntilRun(TaskRunner taskQueue) {
29         postDelayedTaskAndBlockUntilRun(taskQueue, 0);
30     }
31 
postDelayedTaskAndBlockUntilRun(TaskRunner taskQueue, long delay)32     public static void postDelayedTaskAndBlockUntilRun(TaskRunner taskQueue, long delay) {
33         final Object lock = new Object();
34         final AtomicBoolean taskExecuted = new AtomicBoolean();
35         taskQueue.postDelayedTask(
36                 () -> {
37                     synchronized (lock) {
38                         taskExecuted.set(true);
39                         lock.notify();
40                     }
41                 },
42                 delay);
43         synchronized (lock) {
44             try {
45                 while (!taskExecuted.get()) {
46                     lock.wait();
47                 }
48             } catch (InterruptedException ie) {
49                 ie.printStackTrace();
50             }
51         }
52     }
53 
postThreeTasksInOrder(TaskRunner taskQueue, List<Integer> orderList)54     public static void postThreeTasksInOrder(TaskRunner taskQueue, List<Integer> orderList) {
55         postRecordOrderTask(taskQueue, orderList, 1);
56         postRecordOrderTask(taskQueue, orderList, 2);
57         postRecordOrderTask(taskQueue, orderList, 3);
58     }
59 
postThreeDelayedTasksInOrder(TaskRunner taskQueue, List<Integer> orderList)60     public static void postThreeDelayedTasksInOrder(TaskRunner taskQueue, List<Integer> orderList) {
61         postRecordOrderDelayedTask(taskQueue, orderList, 1, 1);
62         postRecordOrderDelayedTask(taskQueue, orderList, 2, 1);
63         postRecordOrderDelayedTask(taskQueue, orderList, 3, 1);
64     }
65 
66     /**
67      * A helper which posts a task on the handler which when run blocks until unblock() is called.
68      */
69     public static class HandlerBlocker {
70         final Handler mHandler;
71         final Object mLock = new Object();
72         final AtomicBoolean mTaskExecuted = new AtomicBoolean();
73 
HandlerBlocker(Handler handler)74         public HandlerBlocker(Handler handler) {
75             mHandler = handler;
76         }
77 
78         /** Posts a task that blocks until unblock() is called. */
postBlockingTask()79         public void postBlockingTask() {
80             mHandler.post(
81                     () -> {
82                         synchronized (mLock) {
83                             try {
84                                 while (!mTaskExecuted.get()) {
85                                     mLock.wait();
86                                 }
87                             } catch (InterruptedException ie) {
88                                 ie.printStackTrace();
89                             }
90                         }
91                     });
92         }
93 
unblock()94         public void unblock() {
95             synchronized (mLock) {
96                 mTaskExecuted.set(true);
97                 mLock.notify();
98             }
99         }
100     }
101     ;
102 
103     /** Waits until the looper's MessageQueue becomes idle. */
preNativeRunUntilIdle(HandlerThread handlerThread)104     public static void preNativeRunUntilIdle(HandlerThread handlerThread) {
105         final Object lock = new Object();
106         final AtomicBoolean taskExecuted = new AtomicBoolean();
107 
108         new Handler(handlerThread.getLooper())
109                 .post(
110                         () -> {
111                             Looper.myQueue()
112                                     .addIdleHandler(
113                                             () -> {
114                                                 synchronized (lock) {
115                                                     taskExecuted.set(true);
116                                                     lock.notify();
117                                                 }
118                                                 return false;
119                                             });
120                         });
121 
122         synchronized (lock) {
123             try {
124                 while (!taskExecuted.get()) {
125                     lock.wait();
126                 }
127             } catch (InterruptedException ie) {
128                 ie.printStackTrace();
129             }
130         }
131     }
132 }
133