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.assertNotSame;
23 import static org.junit.Assert.assertNull;
24 import static org.junit.Assert.assertTrue;
25 import static org.junit.Assert.fail;
26 
27 import android.os.Bundle;
28 import android.os.Handler;
29 import android.os.Looper;
30 import android.os.Message;
31 import android.os.Parcel;
32 import android.platform.test.annotations.AppModeSdkSandbox;
33 import android.platform.test.annotations.IgnoreUnderRavenwood;
34 import android.platform.test.ravenwood.RavenwoodRule;
35 
36 import androidx.test.runner.AndroidJUnit4;
37 
38 import org.junit.Before;
39 import org.junit.Rule;
40 import org.junit.Test;
41 import org.junit.runner.RunWith;
42 
43 import java.util.concurrent.CompletableFuture;
44 import java.util.concurrent.CountDownLatch;
45 import java.util.concurrent.TimeUnit;
46 
47 @AppModeSdkSandbox(reason = "Allow test in the SDK sandbox (does not prevent other modes).")
48 @RunWith(AndroidJUnit4.class)
49 public class MessageTest {
50     @Rule
51     public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
52             .setProvideMainThread(true).build();
53 
54     public static final int WHAT = 1;
55     public static final int ARG1 = 1;
56     public static final int ARG2 = 2;
57     public static final String KEY = "android";
58     public static final int VALUE = 3;
59 
60     private Message mMessage;
61     private CountDownLatch mMessageHandlerCalled;
62 
63     private Handler mHandler;
64 
65     private Runnable mRunnable = new Runnable() {
66         public void run() {
67         }
68     };
69 
70     final Object OBJ = new Object();
71 
72     @Before
setUp()73     public void setUp() throws Exception {
74         mMessage = new Message();
75         mMessageHandlerCalled = new CountDownLatch(1);
76         mHandler = new Handler(Looper.getMainLooper()) {
77             public void handleMessage(Message msg) {
78                 mMessageHandlerCalled.countDown();
79             }
80         };
81     }
82 
83     @Test
testConstructor()84     public void testConstructor() {
85         new Message();
86     }
87 
88     @Test
testAccessMessageProperties()89     public void testAccessMessageProperties() {
90         assertEquals(0, mMessage.getWhen());
91         mMessage.setTarget(mHandler);
92         assertEquals(mHandler, mMessage.getTarget());
93 
94         assertNull(mMessage.getCallback());
95         Message expected = Message.obtain(mHandler, mRunnable);
96         assertEquals(mRunnable, expected.getCallback());
97 
98         Bundle bundle = mMessage.getData();
99         assertNotNull(bundle);
100         Bundle expectedBundle = new Bundle();
101         mMessage.setData(expectedBundle);
102         assertNotNull(mMessage.getData());
103         assertNotSame(bundle, mMessage.getData());
104         assertEquals(expectedBundle, mMessage.getData());
105 
106         assertEquals(0, mMessage.describeContents());
107     }
108 
109     @Test
testObtain()110     public void testObtain() {
111         Message message = Message.obtain();
112         assertNotNull(message);
113         assertEquals(0, message.what);
114         assertEquals(0, message.arg1);
115         assertEquals(0, message.arg2);
116         assertNull(message.obj);
117         assertNull(message.replyTo);
118         assertNull(message.getTarget());
119         assertNull(message.getCallback());
120         assertNull(message.peekData());
121     }
122 
123     @Test
testObtain2()124     public void testObtain2() {
125         Message message = Message.obtain(mHandler, WHAT, ARG1, ARG2, OBJ);
126         Message expected = Message.obtain(message);
127 
128         assertEquals(message.getTarget(), expected.getTarget());
129         assertEquals(message.what, expected.what);
130         assertEquals(message.arg1, expected.arg1);
131         assertEquals(message.arg2, expected.arg2);
132         assertEquals(message.obj, expected.obj);
133     }
134 
135     @Test
testObtain3()136     public void testObtain3() {
137         Message expected = Message.obtain(mHandler);
138         assertEquals(mHandler, expected.getTarget());
139     }
140 
141     @Test
testObtain4()142     public void testObtain4() {
143         Message expected = Message.obtain(mHandler, mRunnable);
144         assertEquals(mHandler, expected.getTarget());
145         assertEquals(mRunnable, expected.getCallback());
146     }
147 
148     @Test
testObtain5()149     public void testObtain5() {
150         Message expected = Message.obtain(mHandler, WHAT);
151         assertEquals(mHandler, expected.getTarget());
152         assertEquals(WHAT, expected.what);
153     }
154 
155     @Test
testObtain6()156     public void testObtain6() {
157         Message expected = Message.obtain(mHandler, WHAT, OBJ);
158         assertEquals(mHandler, expected.getTarget());
159         assertEquals(WHAT, expected.what);
160         assertEquals(OBJ, expected.obj);
161     }
162 
163     @Test
testObtain7()164     public void testObtain7() {
165         Message expected = Message.obtain(mHandler, WHAT, ARG1, ARG2);
166         assertEquals(mHandler, expected.getTarget());
167         assertEquals(WHAT, expected.what);
168         assertEquals(ARG1, expected.arg1);
169         assertEquals(ARG2, expected.arg2);
170     }
171 
172     @Test
testObtain8()173     public void testObtain8() {
174         Message expected = Message.obtain(mHandler, WHAT, ARG1, ARG2, OBJ);
175         assertEquals(mHandler, expected.getTarget());
176         assertEquals(WHAT, expected.what);
177         assertEquals(ARG1, expected.arg1);
178         assertEquals(ARG2, expected.arg2);
179         assertEquals(OBJ, expected.obj);
180     }
181 
182     @Test
testToString()183     public void testToString() {
184         assertNotNull(mMessage.toString());
185     }
186 
187     @Test
testPeekData()188     public void testPeekData() {
189         Bundle expected = new Bundle();
190         assertNull(mMessage.peekData());
191         mMessage.setData(expected);
192         assertNotNull(mMessage.peekData());
193         assertEquals(expected, mMessage.peekData());
194     }
195 
196     @Test
testCopyFrom()197     public void testCopyFrom() {
198         Message message = Message.obtain(mHandler, WHAT, ARG1, ARG2, OBJ);
199         Bundle bundle = new Bundle();
200         bundle.putInt(KEY, VALUE);
201         message.setData(bundle);
202         message.setAsynchronous(true);
203         mMessage.copyFrom(message);
204         assertEquals(WHAT, mMessage.what);
205         assertEquals(ARG1, mMessage.arg1);
206         assertEquals(ARG2, mMessage.arg2);
207         assertEquals(OBJ, mMessage.obj);
208         assertEquals(VALUE, mMessage.getData().getInt(KEY));
209         assertTrue(mMessage.isAsynchronous());
210     }
211 
212     @Test
testRecycle()213     public void testRecycle() {
214         Message message = Message.obtain(mHandler, WHAT, ARG1, ARG2, OBJ);
215         message.recycle();
216         assertEquals(0, message.what);
217         assertEquals(0, message.arg1);
218         assertEquals(0, message.arg2);
219         assertNull(message.obj);
220         assertNull(message.replyTo);
221         assertNull(message.getTarget());
222         assertNull(message.getCallback());
223         assertNull(message.peekData());
224     }
225 
226     @Test
227     @IgnoreUnderRavenwood(blockedBy = android.os.Messenger.class)
testWriteToParcel()228     public void testWriteToParcel() {
229         Message message = Message.obtain(mHandler, WHAT, ARG1, ARG2);
230         Bundle bundle = new Bundle();
231         bundle.putInt(KEY, VALUE);
232         message.setData(bundle);
233         Parcel parcel = Parcel.obtain();
234         message.writeToParcel(parcel, 0);
235         parcel.setDataPosition(0);
236         mMessage = Message.CREATOR.createFromParcel(parcel);
237         assertNull(mMessage.getTarget());
238         assertEquals(WHAT, mMessage.what);
239         assertEquals(ARG1, mMessage.arg1);
240         assertEquals(ARG2, mMessage.arg2);
241         assertEquals(VALUE, mMessage.getData().getInt(KEY));
242 
243         message = Message.obtain(mHandler, WHAT, ARG1, ARG2, OBJ);
244         try {
245             message.writeToParcel(parcel, 1);
246             fail("should throw excetion");
247         } catch (RuntimeException e) {
248             //expected
249         }
250     }
251 
252     @Test
testSendToTarget()253     public void testSendToTarget() throws Exception {
254         try {
255             mMessage.sendToTarget();
256             fail("should throw exception");
257         } catch (Exception e) {
258             //expected
259         }
260 
261         Message message = Message.obtain(mHandler);
262         assertFalse(mMessageHandlerCalled.getCount() == 0);
263         message.sendToTarget();
264         assertTrue(mMessageHandlerCalled.await(1, TimeUnit.SECONDS));
265     }
266 
267     @Test
testAsynchronous()268     public void testAsynchronous() {
269         Message message = Message.obtain();
270         assertFalse(message.isAsynchronous());
271 
272         message.setAsynchronous(true);
273         assertTrue(message.isAsynchronous());
274 
275         message.setAsynchronous(false);
276         assertFalse(message.isAsynchronous());
277     }
278 
279     @Test
testRecycleThrowsIfMessageAlreadyRecycled()280     public void testRecycleThrowsIfMessageAlreadyRecycled() {
281         Message message = Message.obtain();
282         message.recycle();
283 
284         try {
285             message.recycle();
286             fail("should throw IllegalStateException");
287         } catch (IllegalStateException ex) {
288             // expected
289         }
290     }
291 
292     @Test
testSendMessageThrowsIfMessageAlreadyRecycled()293     public void testSendMessageThrowsIfMessageAlreadyRecycled() {
294         Message message = Message.obtain();
295         message.recycle();
296 
297         try {
298             mHandler.sendMessage(message);
299             fail("should throw IllegalStateException");
300         } catch (IllegalStateException ex) {
301             // expected
302         }
303     }
304 
305     @Test
testRecycleThrowsIfMessageIsBeingDelivered()306     public void testRecycleThrowsIfMessageIsBeingDelivered() throws Exception {
307         final CompletableFuture<IllegalStateException> res = new CompletableFuture<>();
308         Handler handler = new Handler(mHandler.getLooper()) {
309             @Override
310             public void handleMessage(Message msg) {
311                 try {
312                     msg.recycle();
313                 } catch (IllegalStateException ex) {
314                     res.complete(ex);
315                 }
316             }
317         };
318         handler.sendEmptyMessage(WHAT);
319         assertNotNull("should throw IllegalStateException", res.get(1, TimeUnit.SECONDS));
320     }
321 
322     @Test
testSendMessageThrowsIfMessageIsBeingDelivered()323     public void testSendMessageThrowsIfMessageIsBeingDelivered() throws Exception {
324         final CompletableFuture<IllegalStateException> res = new CompletableFuture<>();
325         Handler handler = new Handler(mHandler.getLooper()) {
326             @Override
327             public void handleMessage(Message msg) {
328                 try {
329                     mHandler.sendMessage(msg);
330                 } catch (IllegalStateException ex) {
331                     res.complete(ex);
332                 }
333             }
334         };
335         handler.sendEmptyMessage(WHAT);
336         assertNotNull("should throw IllegalStateException", res.get(1, TimeUnit.SECONDS));
337     }
338 }
339