• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 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 
20 import android.content.ComponentName;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.ServiceConnection;
24 import android.os.Handler;
25 import android.os.HandlerThread;
26 import android.os.IBinder;
27 import android.os.IInterface;
28 import android.os.Looper;
29 import android.os.Message;
30 import android.os.Messenger;
31 import android.os.Parcel;
32 import android.os.RemoteException;
33 import android.os.ResultReceiver;
34 import android.test.AndroidTestCase;
35 
36 import java.io.FileDescriptor;
37 
38 public class MessengerTest extends AndroidTestCase {
39 
40     private Messenger mMessenger;
41     private Message mMessage;
42     private boolean mResult;
43     private Messenger mServiceMessenger;
44     private static final int MSG_ARG1 = 100;
45     private static final int MSG_ARG2 = 1000;
46     private static final int WHAT = 2008;
47     private Handler mHandler = new Handler(Looper.getMainLooper()) {
48         @Override
49         public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
50             mResult = true;
51             mMessage = msg;
52             return super.sendMessageAtTime(msg, uptimeMillis);
53         }
54     };
55 
56     private final IBinder mIBinder = new IBinder() {
57 
58         public String getInterfaceDescriptor() throws RemoteException {
59             return null;
60         }
61 
62         public boolean isBinderAlive() {
63             return false;
64         }
65 
66         public void linkToDeath(DeathRecipient recipient, int flags) throws RemoteException {
67         }
68 
69         public boolean pingBinder() {
70             return false;
71         }
72 
73         public IInterface queryLocalInterface(String descriptor) {
74             return null;
75         }
76 
77         public boolean transact(int code, Parcel data, Parcel reply, int flags)
78                 throws RemoteException {
79             return false;
80         }
81 
82         public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
83             return false;
84         }
85 
86         public void dump(FileDescriptor fd, String[] args) throws RemoteException {
87         }
88 
89         public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException {
90         }
91 
92         @Override
93         public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
94                 String[] args, ResultReceiver resultReceiver) {
95         }
96 
97     };
98 
99     // Create another messenger to send msg.
100     private ServiceConnection mConnection = new ServiceConnection() {
101         public void onServiceConnected(ComponentName name, IBinder service) {
102             synchronized (MessengerTest.this) {
103                 mServiceMessenger = new Messenger(service);
104                 MessengerTest.this.notifyAll();
105             }
106         }
107 
108         public void onServiceDisconnected(ComponentName name) {
109             mServiceMessenger = null;
110         }
111     };
112 
113     @Override
setUp()114     protected void setUp() throws Exception {
115 
116         super.setUp();
117         mMessenger = new Messenger(mHandler);
118         getContext().bindService(new Intent(mContext, MessengerService.class), mConnection,
119                 Context.BIND_AUTO_CREATE);
120         synchronized (this) {
121             while (mServiceMessenger == null) {
122                 wait();
123             }
124         }
125     }
126 
127     @Override
tearDown()128     protected void tearDown() throws Exception {
129         super.tearDown();
130         getContext().unbindService(mConnection);
131     }
132 
testConstructorAndEquals()133     public void testConstructorAndEquals() {
134         Messenger messenger = new Messenger(mHandler);
135         Messenger objMessenger = new Messenger(mHandler);
136         assertTrue(messenger.equals(objMessenger));
137         messenger = new Messenger(mIBinder);
138         assertFalse(messenger.equals(objMessenger));
139     }
140 
testSend()141     public void testSend() throws RemoteException, InterruptedException {
142         // messenger used by its own thread.
143         Message message = Message.obtain(mHandler, WHAT, MSG_ARG1, MSG_ARG2);
144         mMessenger.send(message);
145         assertTrue(mResult);
146         assertNotNull(mMessage);
147         assertEquals(mMessage.what, message.what);
148         assertEquals(mMessage.arg1, message.arg1);
149         assertEquals(mMessage.arg2, message.arg2);
150 
151         // Used in other process. If the sent msg does not equal to expected, it will throw failure
152         // and the test will fail
153         (new MessengerTestHelper()).doTest(1000, 50);
154     }
155 
testHashCode()156     public void testHashCode() {
157         assertEquals(mMessenger.getBinder().hashCode(), mMessenger.hashCode());
158     }
159 
testGetBinder()160     public void testGetBinder() {
161         Messenger messenger = new Messenger(mIBinder);
162         assertSame(mIBinder, messenger.getBinder());
163         assertNotNull(mMessenger.getBinder());
164     }
165 
testWriteToParcel()166     public void testWriteToParcel() {
167         Parcel parcel = Parcel.obtain();
168         mMessenger.writeToParcel(parcel, 0);
169         parcel.setDataPosition(0);
170         Messenger messenger = Messenger.CREATOR.createFromParcel(parcel);
171         assertTrue(messenger.equals(mMessenger));
172         parcel.recycle();
173     }
174 
testDescribeContents()175     public void testDescribeContents() {
176         assertEquals(0, mMessenger.describeContents());
177     }
178 
testWriteMessengerOrNullToParcel()179     public void testWriteMessengerOrNullToParcel() {
180         Parcel parcelWithMessenger = Parcel.obtain();
181         Messenger.writeMessengerOrNullToParcel(mMessenger, parcelWithMessenger);
182         parcelWithMessenger.setDataPosition(0);
183         Messenger messenger = Messenger.readMessengerOrNullFromParcel(parcelWithMessenger);
184         assertNotNull(messenger);
185         assertTrue(messenger.equals(mMessenger));
186         parcelWithMessenger.recycle();
187 
188         Parcel parcelWithNull = Parcel.obtain();
189         Messenger.writeMessengerOrNullToParcel(null, parcelWithNull);
190         parcelWithNull.setDataPosition(0);
191         messenger = Messenger.readMessengerOrNullFromParcel(parcelWithNull);
192         assertNull(messenger);
193         parcelWithNull.recycle();
194     }
195 
196     /**
197      * This helper class is used for test of MessengerTest. Mainly on control of the message looper.
198      */
199     private class MessengerTestHelper {
200         private boolean mDone = false;
201         private boolean mSuccess = false;
202         private RuntimeException mFailure = null;
203         private Looper mLooper;
204 
205         private Handler mTestHandler;
206         private Messenger mTestMessenger;
207 
init()208         public void init() {
209             synchronized (MessengerTest.this) {
210                 mTestHandler = new Handler() {
211                     public void handleMessage(Message msg) {
212                         MessengerTestHelper.this.handleMessage(msg);
213                     }
214                 };
215                 mTestMessenger = new Messenger(mTestHandler);
216                 try {
217                     MessengerTestHelper.this.executeTest();
218                 } catch (RemoteException e) {
219                     fail(e.getMessage());
220                 }
221             }
222         }
223 
MessengerTestHelper()224         public MessengerTestHelper() {
225         }
226 
executeTest()227         public void executeTest() throws RemoteException {
228             Message msg = Message.obtain();
229             msg.arg1 = MSG_ARG1;
230             msg.arg2 = MSG_ARG2;
231             msg.replyTo = mTestMessenger;
232             // Use another messenger to send msg.
233             mServiceMessenger.send(msg);
234         }
235 
236         /**
237          * This method is used to check if the message sent by another messenger is correctly
238          * handled by this thread. If not equals to expected, there will be a failure thrown.
239          */
handleMessage(Message msg)240         public void handleMessage(Message msg) {
241             if (msg.arg1 != MSG_ARG1) {
242                 failure(new RuntimeException("Message.arg1 is not " + MSG_ARG1 + ", it's "
243                         + msg.arg1));
244                 return;
245             }
246             if (msg.arg2 != MSG_ARG2) {
247                 failure(new RuntimeException("Message.arg2 is not " + MSG_ARG2 + ", it's "
248                         + msg.arg2));
249                 return;
250             }
251             if (!mTestMessenger.equals(msg.replyTo)) {
252                 failure(new RuntimeException("Message.replyTo is not me, it's " + msg.replyTo));
253                 return;
254             }
255             success();
256         }
257 
doTest(long timeout, long interval)258         public void doTest(long timeout, long interval) throws InterruptedException {
259             (new LooperThread()).start();
260 
261             synchronized (this) {
262                 long now = System.currentTimeMillis();
263                 long endTime = now + timeout;
264                 // wait and frequently check if mDone is set.
265                 while (!mDone && now < endTime) {
266                     wait(interval);
267                     now = System.currentTimeMillis();
268                 }
269             }
270 
271             mLooper.quit();
272 
273             if (!mDone) {
274                 throw new RuntimeException("test timed out");
275             }
276             if (!mSuccess) {
277                 throw mFailure;
278             }
279         }
280 
getLooper()281         public Looper getLooper() {
282             return mLooper;
283         }
284 
success()285         public void success() {
286             synchronized (this) {
287                 mSuccess = true;
288                 quit();
289             }
290         }
291 
failure(RuntimeException failure)292         public void failure(RuntimeException failure) {
293             synchronized (this) {
294                 mSuccess = false;
295                 mFailure = failure;
296                 quit();
297             }
298         }
299 
300         class LooperThread extends HandlerThread {
301 
LooperThread()302             public LooperThread() {
303                 super("MessengerLooperThread");
304             }
305 
onLooperPrepared()306             public void onLooperPrepared() {
307                 init();
308                 mLooper = getLooper();
309             }
310 
311             @Override
run()312             public void run() {
313                 super.run();
314                 synchronized (MessengerTestHelper.this) {
315                     mDone = true;
316                     if (!mSuccess && mFailure == null) {
317                         mFailure = new RuntimeException("no failure exception set");
318                     }
319                     MessengerTestHelper.this.notifyAll();
320                 }
321             }
322         }
323 
quit()324         private void quit() {
325             synchronized (this) {
326                 mDone = true;
327                 notifyAll();
328             }
329         }
330     }
331 }
332