1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.server.timezonedetector;
17 
18 import static org.junit.Assert.assertEquals;
19 
20 import android.os.Handler;
21 import android.os.Looper;
22 import android.os.Message;
23 
24 /**
25  * A Handler that can track posts/sends and wait for them to be completed.
26  */
27 public class TestHandler extends Handler {
28 
29     private final Object mMonitor = new Object();
30     private int mMessagesProcessed = 0;
31     private int mMessagesSent = 0;
32 
TestHandler(Looper looper)33     public TestHandler(Looper looper) {
34         super(looper);
35     }
36 
37     @Override
sendMessageAtTime(Message msg, long uptimeMillis)38     public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
39         synchronized (mMonitor) {
40             mMessagesSent++;
41         }
42 
43         Runnable callback = msg.getCallback();
44         // Have the callback increment the mMessagesProcessed when it is done. It will notify
45         // any threads waiting for all messages to be processed if appropriate.
46         Runnable newCallback = () -> {
47             callback.run();
48             synchronized (mMonitor) {
49                 mMessagesProcessed++;
50                 if (mMessagesSent == mMessagesProcessed) {
51                     mMonitor.notifyAll();
52                 }
53             }
54         };
55         msg.setCallback(newCallback);
56         return super.sendMessageAtTime(msg, uptimeMillis);
57     }
58 
59     /** Asserts the number of messages posted or sent is as expected. */
assertTotalMessagesEnqueued(int expected)60     public void assertTotalMessagesEnqueued(int expected) {
61         synchronized (mMonitor) {
62             assertEquals(expected, mMessagesSent);
63         }
64     }
65 
66     /**
67      * Waits for all enqueued work to be completed before returning.
68      */
waitForMessagesToBeProcessed()69     public void waitForMessagesToBeProcessed() throws InterruptedException {
70         synchronized (mMonitor) {
71             if (mMessagesSent != mMessagesProcessed) {
72                 mMonitor.wait();
73             }
74         }
75     }
76 }
77