1 /*
2  * Copyright (C) 2009 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 
17 package android.os.cts;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertNotNull;
22 import static org.junit.Assert.assertNull;
23 import static org.junit.Assert.assertSame;
24 import static org.junit.Assert.assertTrue;
25 import static org.junit.Assert.fail;
26 
27 import android.os.Handler;
28 import android.os.Handler.Callback;
29 import android.os.Looper;
30 import android.os.Message;
31 import android.os.SystemClock;
32 import android.platform.test.annotations.AppModeSdkSandbox;
33 import android.platform.test.ravenwood.RavenwoodRule;
34 import android.util.Printer;
35 
36 import androidx.test.runner.AndroidJUnit4;
37 
38 import com.android.compatibility.common.util.TestThread;
39 
40 import org.junit.After;
41 import org.junit.Before;
42 import org.junit.Rule;
43 import org.junit.Test;
44 import org.junit.runner.RunWith;
45 
46 @AppModeSdkSandbox(reason = "Allow test in the SDK sandbox (does not prevent other modes).")
47 @RunWith(AndroidJUnit4.class)
48 public class HandlerTest {
49     @Rule
50     public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
51             .setProvideMainThread(true).build();
52 
53     public static final int MESSAGE_WHAT = 3;
54 
55     // time when message should be handled.
56     static final int RUNTIME = 300;
57 
58     // time when check whether the message is handled.
59     static final long DELAYED = RUNTIME + 50;
60 
61     // Handler
62     private Handler mHandler;
63     private MockHandler mHandler1;
64     private final Object mLock = new Object();
65 
66     @Before
setUp()67     public void setUp() throws Exception {
68         mHandler = new Handler(Looper.getMainLooper());
69         mHandler1 = new MockHandler(Looper.getMainLooper());
70     }
71 
72     @After
tearDown()73     public void tearDown() throws Exception {
74         mHandler1.reset();
75     }
76 
77     @Test
testConstructor()78     public void testConstructor() throws Throwable {
79         final Callback cb = new Callback() {
80             public boolean handleMessage(Message msg) {
81                 return false;
82             }
83         };
84 
85         new TestThread(new Runnable() {
86             public void run() {
87                 Looper.prepare();
88                 new Handler();
89                 new Handler(cb);
90             }
91         }).runTest(RUNTIME);
92 
93         // new the Handler instance
94         new Handler(Looper.getMainLooper());
95         new Handler(Looper.getMainLooper(), cb);
96     }
97 
98     @Test
testPostAtTime1()99     public void testPostAtTime1() {
100         MockRunnable r = new MockRunnable();
101         assertTrue(mHandler.postAtTime(r, SystemClock.uptimeMillis() + RUNTIME));
102         assertFalse(r.isRun());
103         sleep(DELAYED);
104         assertTrue(r.isRun());
105         mHandler.removeCallbacks(r);
106     }
107 
108     @Test
testPostAtTime2()109     public void testPostAtTime2() {
110         MockRunnable r = new MockRunnable();
111         Object token = new Object();
112         assertTrue(mHandler.postAtTime(r, token, SystemClock.uptimeMillis() + RUNTIME));
113         assertFalse(r.isRun());
114         sleep(DELAYED);
115         assertTrue(r.isRun());
116         mHandler.removeCallbacks(r);
117     }
118 
119     @Test
testSendMessageAtTime()120     public void testSendMessageAtTime() {
121         Message msg = mHandler1.obtainMessage();
122         assertTrue(mHandler1.sendMessageAtTime(msg, SystemClock.uptimeMillis() + RUNTIME));
123         assertNull(mHandler1.message);
124         sleep(DELAYED);
125         assertSame(msg, mHandler1.message);
126         mHandler1.removeMessages(msg.what);
127     }
128 
129     @Test
testDump()130     public void testDump() {
131         final String prefix = "AndroidTest";
132         MockPrinter pw = new MockPrinter();
133         mHandler.dump(pw, prefix);
134     }
135 
136     @Test
testHasMessagesWithInt()137     public void testHasMessagesWithInt() {
138         Message msg = mHandler.obtainMessage();
139         assertFalse(mHandler.hasMessages(msg.what));
140         mHandler.sendMessageAtTime(msg, SystemClock.uptimeMillis() + RUNTIME);
141         assertTrue(mHandler.hasMessages(msg.what));
142         mHandler.removeMessages(msg.what);
143         assertFalse(mHandler.hasMessages(msg.what));
144     }
145 
146     @Test
testHasMessagesWithObject()147     public void testHasMessagesWithObject() {
148         Message msg = mHandler.obtainMessage();
149         msg.obj = new Object();
150         assertFalse(mHandler.hasMessages(msg.what, msg.obj));
151         mHandler.sendMessageAtTime(msg, SystemClock.uptimeMillis() + RUNTIME);
152         assertTrue(mHandler.hasMessages(msg.what, msg.obj));
153         mHandler.removeMessages(msg.what);
154         assertFalse(mHandler.hasMessages(msg.what, msg.obj));
155     }
156 
157     @Test
testRemoveCallbacksAndMessages()158     public void testRemoveCallbacksAndMessages() {
159         Message msg = mHandler1.obtainMessage();
160         mHandler1.sendMessageAtTime(msg, SystemClock.uptimeMillis() + RUNTIME);
161         sleep(RUNTIME / 2);
162 
163         // Test the obj == null
164         mHandler1.removeCallbacksAndMessages(null);
165         sleep(RUNTIME / 2);
166         assertNull(mHandler1.message);
167         mHandler1.reset();
168 
169         msg = mHandler1.obtainMessage();
170         msg.obj = new Object();
171         mHandler1.sendMessageAtTime(msg, SystemClock.uptimeMillis() + RUNTIME);
172         sleep(RUNTIME / 2);
173 
174         // Test the obj == p.obj for message
175         mHandler1.removeCallbacksAndMessages(msg.obj);
176         sleep(RUNTIME / 2);
177         assertNull(mHandler1.message);
178         mHandler1.reset();
179 
180         // Test remove a callback
181         final Object obj = new Object();
182         MockRunnable mr1 = new MockRunnable();
183         mHandler1.postAtTime(mr1, obj, SystemClock.uptimeMillis() + RUNTIME);
184         sleep(RUNTIME / 2);
185         mHandler1.removeCallbacksAndMessages(obj);
186         sleep(RUNTIME / 2);
187         assertFalse(mr1.isRun());
188 
189         // test remove a wrong callback
190         mr1 = new MockRunnable();
191         mHandler1.postAtTime(mr1, obj, SystemClock.uptimeMillis() + RUNTIME);
192         sleep(DELAYED / 2);
193         mHandler1.removeCallbacksAndMessages(new Object());
194         sleep(DELAYED / 2);
195         assertTrue(mr1.isRun());
196     }
197 
198     @Test
testSendEmptyMessageAtTime()199     public void testSendEmptyMessageAtTime() {
200         long uptime = SystemClock.uptimeMillis() + RUNTIME;
201         assertTrue(mHandler1.sendEmptyMessageAtTime(MESSAGE_WHAT, uptime));
202         assertEquals(0, mHandler1.what);
203         sleep(DELAYED);
204         assertEquals(MESSAGE_WHAT, mHandler1.what);
205         mHandler1.removeMessages(MESSAGE_WHAT);
206     }
207 
208     @Test
testGetLooper()209     public void testGetLooper() {
210         // new the Handler instance
211         Looper looper = Looper.getMainLooper();
212         Handler handler = new Handler(looper);
213         assertSame(looper, handler.getLooper());
214     }
215 
216     @Test
testRemoveCallbacks()217     public void testRemoveCallbacks() {
218         // test remove right object.
219         MockRunnable r = new MockRunnable();
220         mHandler.postAtTime(r, SystemClock.uptimeMillis() + RUNTIME);
221         sleep(DELAYED / 2);
222         mHandler.removeCallbacks(r);
223         sleep(DELAYED / 2);
224         assertFalse(r.isRun());
225 
226         // test remove wrong object.
227         r = new MockRunnable();
228         MockRunnable mr = new MockRunnable();
229         mHandler.postAtTime(r, SystemClock.uptimeMillis() + RUNTIME);
230         sleep(DELAYED / 2);
231         mHandler.removeCallbacks(mr);
232         sleep(DELAYED / 2);
233         assertTrue(r.isRun());
234     }
235 
236     @Test
testRemoveCallbacksWithObject()237     public void testRemoveCallbacksWithObject() {
238         // test remove right object.
239         MockRunnable r1 = new MockRunnable();
240         Object token = new Object();
241         mHandler.postAtTime(r1, token, SystemClock.uptimeMillis() + RUNTIME);
242         sleep(DELAYED / 2);
243         mHandler.removeCallbacks(r1, token);
244         sleep(DELAYED / 2);
245         assertFalse(r1.isRun());
246 
247         // test remove wrong object.
248         r1 = new MockRunnable();
249         MockRunnable r2 = new MockRunnable();
250 
251         mHandler.postAtTime(r1, token, SystemClock.uptimeMillis() + RUNTIME);
252         sleep(DELAYED / 2);
253         mHandler.removeCallbacks(r2, token);
254         sleep(DELAYED / 2);
255         assertTrue(r1.isRun());
256 
257         // test remove with right callback and wrong token
258         mHandler.postAtTime(r1, token, SystemClock.uptimeMillis() + RUNTIME);
259         Object wrongToken = new Object();
260         sleep(DELAYED / 2);
261         mHandler.removeCallbacks(r1, wrongToken);
262         sleep(DELAYED / 2);
263         assertTrue(r1.isRun());
264     }
265 
266     @Test
testRemoveMessages()267     public void testRemoveMessages() {
268         // test remove right message
269         Message msg = mHandler1.obtainMessage();
270         msg.what = 100;
271         mHandler1.sendMessageAtTime(msg, SystemClock.uptimeMillis() + RUNTIME);
272         sleep(DELAYED / 2);
273         mHandler1.removeMessages(msg.what);
274         sleep(DELAYED / 2);
275         assertNull(mHandler1.message);
276         assertEquals(0, mHandler1.what);
277         mHandler1.reset();
278 
279         // test remove wrong message
280         msg = mHandler1.obtainMessage();
281         msg.what = 100;
282         mHandler1.sendMessageAtTime(msg, SystemClock.uptimeMillis() + RUNTIME);
283         sleep(DELAYED / 2);
284         mHandler1.removeMessages(101);
285         sleep(DELAYED / 2);
286         assertEquals(100, mHandler1.what);
287     }
288 
289     @Test
testRemoveMessagesWithObject()290     public void testRemoveMessagesWithObject() {
291         // test remove right message
292         Message msg = mHandler1.obtainMessage();
293         msg.obj = new Object();
294         msg.what = 100;
295         mHandler1.sendMessageAtTime(msg, SystemClock.uptimeMillis() + RUNTIME);
296         sleep(DELAYED / 2);
297         mHandler1.removeMessages(msg.what, msg.obj);
298         sleep(DELAYED / 2);
299         assertNull(mHandler1.message);
300         assertEquals(0, mHandler1.what);
301         mHandler1.reset();
302 
303         // test remove wrong message
304         msg = mHandler1.obtainMessage();
305         msg.obj = new Object();
306         msg.what = 100;
307         Message wrongMessage = mHandler1.obtainMessage();
308         wrongMessage.obj = new Object();
309         wrongMessage.what = 111;
310         mHandler1.sendMessageAtTime(msg, SystemClock.uptimeMillis() + RUNTIME);
311         sleep(DELAYED / 2);
312         mHandler1.removeMessages(msg.what, wrongMessage.obj);
313         sleep(DELAYED / 2);
314         assertEquals(100, mHandler1.what);
315     }
316 
317     @Test
testSendMessage()318     public void testSendMessage() {
319         Message msg = mHandler1.obtainMessage();
320         assertTrue(mHandler1.sendMessage(msg));
321         sleep(DELAYED);
322         assertSame(msg, mHandler1.message);
323         mHandler1.removeMessages(msg.what);
324     }
325 
326     @Test
testObtainMessage()327     public void testObtainMessage() {
328          Message msg = mHandler.obtainMessage();
329          assertNotNull(msg);
330          assertEquals(mHandler, msg.getTarget());
331     }
332 
333     @Test
testObtainMessageWithInt()334     public void testObtainMessageWithInt() {
335          // new the Handler instance
336          Handler handler = new Handler(Looper.getMainLooper());
337          Message msg = handler.obtainMessage();
338          msg.what = 100;
339          Message msg1 = mHandler.obtainMessage(msg.what);
340          assertNotNull(msg1);
341          assertEquals(mHandler, msg1.getTarget());
342          assertEquals(msg.what, msg1.what);
343     }
344 
345     @Test
testObtainMessageWithIntObject()346     public void testObtainMessageWithIntObject() {
347         // new the Handler instance
348         Handler handler = new Handler(Looper.getMainLooper());
349         Message msg = handler.obtainMessage();
350         msg.what = 100;
351         msg.obj = new Object();
352         Message msg1 = mHandler.obtainMessage(msg.what, msg.obj);
353         assertNotNull(msg1);
354         assertEquals(mHandler, msg1.getTarget());
355         assertEquals(msg.what, msg1.what);
356         assertSame(msg.obj, msg1.obj);
357     }
358 
359     @Test
testObtainMessageWithMutiInt()360     public void testObtainMessageWithMutiInt() {
361         // new the Handler instance
362         Handler handler = new Handler(Looper.getMainLooper());
363         Message msg = handler.obtainMessage();
364         msg.what = 100;
365         msg.arg1 = 101;
366         msg.arg2 = 102;
367         Message msg1 = mHandler.obtainMessage(msg.what, msg.arg1, msg.arg2);
368         assertNotNull(msg1);
369         assertEquals(mHandler, msg1.getTarget());
370         assertEquals(msg.what, msg1.what);
371         assertEquals(msg.arg1, msg1.arg1);
372         assertEquals(msg.arg2, msg1.arg2);
373     }
374 
375     @Test
testObtainMessageWithMutiIntObject()376     public void testObtainMessageWithMutiIntObject() {
377         // new the Handler instance
378         Handler handler = new Handler(Looper.getMainLooper());
379         Message msg = handler.obtainMessage();
380         msg.what = 100;
381         msg.arg1 = 1000;
382         msg.arg2 = 2000;
383         msg.obj = new Object();
384         Message msg1 = mHandler.obtainMessage(msg.what, msg.arg1, msg.arg2, msg.obj);
385         assertNotNull(msg1);
386         assertEquals(mHandler, msg1.getTarget());
387         assertEquals(msg.arg1, msg1.arg1);
388         assertEquals(msg.arg2, msg1.arg2);
389         assertSame(msg.obj, msg1.obj);
390     }
391 
392     @Test
testSendMessageAtFrontOfQueue()393     public void testSendMessageAtFrontOfQueue() {
394         Message lateMsg = mHandler1.obtainMessage();
395         mHandler1.sendEmptyMessageAtTime(lateMsg.what, SystemClock.uptimeMillis() + RUNTIME * 5);
396         Message msg = mHandler1.obtainMessage();
397         msg.what = 100;
398         assertTrue(mHandler1.sendMessageAtFrontOfQueue(msg));
399         sleep(DELAYED);
400         assertSame(msg, mHandler1.message);
401         mHandler1.removeMessages(msg.what);
402     }
403 
404     @Test
testPostDelayed()405     public void testPostDelayed() {
406         MockRunnable r = new MockRunnable();
407         assertTrue(mHandler.postDelayed(r, DELAYED));
408         assertFalse(r.isRun());
409         sleep(DELAYED + 500);
410         assertTrue(r.isRun());
411         mHandler.removeCallbacks(r);
412     }
413 
414     @Test
testPostAtFrontOfQueue()415     public void testPostAtFrontOfQueue() {
416         MockRunnable r = new MockRunnable();
417         MockRunnable mr = new MockRunnable();
418         assertFalse(r.isRun());
419         assertTrue(mHandler.postDelayed(mr, DELAYED));
420         assertTrue(mHandler.postAtFrontOfQueue(r));
421         sleep(DELAYED / 2);
422         assertTrue(r.isRun());
423         mHandler.removeCallbacks(r);
424     }
425 
426     @Test
testSendMessageDelayed()427     public void testSendMessageDelayed() {
428         Message msg = mHandler1.obtainMessage();
429         assertTrue(mHandler1.sendMessageDelayed(msg, DELAYED));
430         assertNull(mHandler1.message);
431         sleep(DELAYED + 500);
432         assertSame(msg, mHandler1.message);
433         mHandler1.removeMessages(msg.what);
434     }
435 
436     @Test
testPost()437     public void testPost() {
438         MockRunnable r = new MockRunnable();
439         assertFalse(r.isRun());
440         assertTrue(mHandler.post(r));
441         sleep(DELAYED);
442         assertTrue(r.isRun());
443         mHandler.removeCallbacks(r);
444     }
445 
446     @Test
testSendEmptyMessageDelayed()447     public void testSendEmptyMessageDelayed() {
448         Message msg = mHandler1.obtainMessage();
449         msg.what = 100;
450         assertTrue(mHandler1.sendEmptyMessageDelayed(msg.what, DELAYED));
451         sleep(DELAYED + 500);
452         assertEquals(msg.what, mHandler1.what);
453         mHandler1.removeMessages(msg.what);
454     }
455 
456     @Test
testDispatchMessage1()457     public void testDispatchMessage1() {
458         // new the Handler instance
459         MockHandler handler = new MockHandler();
460         MockRunnable callback = new MockRunnable();
461         Message msg = Message.obtain(handler, callback);
462         handler.dispatchMessage(msg);
463         assertNotNull(msg.getCallback());
464 
465         // Test the if branch
466         assertTrue(callback.isRun());
467     }
468 
469     @Test
testDispatchMessage2()470     public void testDispatchMessage2() {
471         // new the Handler instance
472         MockHandler handler = new MockHandler();
473         Message msg = handler.obtainMessage();
474         handler.dispatchMessage(msg);
475 
476         // Test the else branch
477         assertSame(msg, handler.message);
478     }
479 
480     @Test
testSendEmptyMessage()481     public void testSendEmptyMessage() {
482         Message msg = mHandler1.obtainMessage();
483         msg.what = 100;
484         assertTrue(mHandler1.sendEmptyMessage(msg.what));
485         sleep(DELAYED);
486         assertEquals(msg.what, mHandler1.what);
487         mHandler1.removeMessages(msg.what);
488     }
489 
490     @Test
testToString()491     public void testToString() {
492         assertNotNull(mHandler1.toString());
493     }
494 
495     /**
496      * MockRunnable
497      */
498     private class MockRunnable implements Runnable {
499         // MockRunnable run
500         private boolean mIsRun;
501 
run()502         public void run() {
503             mIsRun = true;
504         }
505 
isRun()506         public boolean isRun() {
507             return mIsRun;
508         }
509     }
510 
511     /**
512      * MockPrinter
513      */
514     private class MockPrinter implements Printer {
515         String mOutput;
516 
println(String x)517         public void println(String x) {
518             mOutput = x;
519         }
520 
getPrint()521         public String getPrint() {
522             return mOutput;
523         }
524     }
525 
526     /**
527      * MockHandler
528      */
529     private class MockHandler extends Handler {
530         public Message message;
531         public int what;
532 
MockHandler()533         MockHandler() {
534             super(Looper.getMainLooper());
535         }
536 
MockHandler(Looper looper)537         MockHandler(Looper looper) {
538             super(looper);
539         }
540 
541         @Override
handleMessage(Message msg)542         public void handleMessage(Message msg) {
543             message = msg;
544             what = message.what;
545         }
546 
reset()547         public void reset() {
548             message = null;
549             what = 0;
550         }
551     }
552 
sleep(long time)553     public void sleep(long time) {
554         try {
555             Thread.sleep(time);
556         } catch (InterruptedException e) {
557             fail(e.getMessage());
558         }
559     }
560 }
561