Home | History | Annotate | Download | only in os
      1 /*
      2  * Copyright (C) 2007 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;
     18 
     19 import android.os.Handler;
     20 import android.os.Message;
     21 import android.os.SystemClock;
     22 import android.test.suitebuilder.annotation.MediumTest;
     23 import junit.framework.TestCase;
     24 
     25 public class MessageQueueTest extends TestCase {
     26 
     27     private static class BaseTestHandler extends TestHandlerThread {
     28         Handler mHandler;
     29         int mLastMessage;
     30         int mCount;
     31 
     32         public BaseTestHandler() {
     33         }
     34 
     35         public void go() {
     36             mHandler = new Handler() {
     37                 public void handleMessage(Message msg) {
     38                     BaseTestHandler.this.handleMessage(msg);
     39                 }
     40             };
     41         }
     42 
     43         public void handleMessage(Message msg) {
     44             if (!msg.isInUse()) {
     45                 failure(new RuntimeException(
     46                         "msg.isInuse is false, should always be true, #" + msg.what));
     47             }
     48             if (mCount <= mLastMessage) {
     49                 if (msg.what != mCount) {
     50                     failure(new RuntimeException(
     51                             "Expected message #" + mCount
     52                                     + ", received #" + msg.what));
     53                 } else if (mCount == mLastMessage) {
     54                     success();
     55                 }
     56                 mCount++;
     57             } else {
     58                 failure(new RuntimeException(
     59                         "Message received after done, #" + msg.what));
     60             }
     61         }
     62     }
     63 
     64     @MediumTest
     65     public void testMessageOrder() throws Exception {
     66         TestHandlerThread tester = new BaseTestHandler() {
     67             public void go() {
     68                 super.go();
     69                 long now = SystemClock.uptimeMillis() + 200;
     70                 mLastMessage = 4;
     71                 mCount = 0;
     72                 mHandler.sendMessageAtTime(mHandler.obtainMessage(2), now + 1);
     73                 mHandler.sendMessageAtTime(mHandler.obtainMessage(3), now + 2);
     74                 mHandler.sendMessageAtTime(mHandler.obtainMessage(4), now + 2);
     75                 mHandler.sendMessageAtTime(mHandler.obtainMessage(0), now + 0);
     76                 mHandler.sendMessageAtTime(mHandler.obtainMessage(1), now + 0);
     77             }
     78         };
     79 
     80         tester.doTest(1000);
     81     }
     82 
     83     @MediumTest
     84     public void testAtFrontOfQueue() throws Exception {
     85         TestHandlerThread tester = new BaseTestHandler() {
     86             public void go() {
     87                 super.go();
     88                 long now = SystemClock.uptimeMillis() + 200;
     89                 mLastMessage = 3;
     90                 mCount = 0;
     91                 mHandler.sendMessageAtTime(mHandler.obtainMessage(3), now);
     92                 mHandler.sendMessageAtFrontOfQueue(mHandler.obtainMessage(2));
     93                 mHandler.sendMessageAtFrontOfQueue(mHandler.obtainMessage(0));
     94             }
     95 
     96             public void handleMessage(Message msg) {
     97                 super.handleMessage(msg);
     98                 if (msg.what == 0) {
     99                     mHandler.sendMessageAtFrontOfQueue(mHandler.obtainMessage(1));
    100                 }
    101             }
    102         };
    103 
    104         tester.doTest(1000);
    105     }
    106 
    107     private static class TestFieldIntegrityHandler extends TestHandlerThread {
    108         Handler mHandler;
    109         int mLastMessage;
    110         int mCount;
    111 
    112         public TestFieldIntegrityHandler() {
    113         }
    114 
    115         public void go() {
    116             mHandler = new Handler() {
    117                 public void handleMessage(Message msg) {
    118                     TestFieldIntegrityHandler.this.handleMessage(msg);
    119                 }
    120             };
    121         }
    122 
    123         public void handleMessage(Message msg) {
    124             if (!msg.isInUse()) {
    125                 failure(new RuntimeException(
    126                         "msg.isInuse is false, should always be true, #" + msg.what));
    127             }
    128             if (mCount <= mLastMessage) {
    129                 if (msg.what != mCount) {
    130                     failure(new RuntimeException(
    131                             "Expected message #" + mCount
    132                                     + ", received #" + msg.what));
    133                 } else if (mCount == mLastMessage) {
    134                     success();
    135                 }
    136                 mCount++;
    137             } else {
    138                 failure(new RuntimeException(
    139                         "Message received after done, #" + msg.what));
    140             }
    141         }
    142     }
    143 
    144     @MediumTest
    145     public void testFieldIntegrity() throws Exception {
    146 
    147         TestHandlerThread tester = new TestFieldIntegrityHandler() {
    148             Bundle mBundle;
    149 
    150             public void go() {
    151                 super.go();
    152                 mLastMessage = 1;
    153                 mCount = 0;
    154                 mHandler.sendMessage(mHandler.obtainMessage(0));
    155             }
    156 
    157             public void handleMessage(Message msg) {
    158                 super.handleMessage(msg);
    159                 if (msg.what == 0) {
    160                     msg.flags = -1;
    161                     msg.what = 1;
    162                     msg.arg1 = 456;
    163                     msg.arg2 = 789;
    164                     msg.obj = this;
    165                     msg.replyTo = null;
    166                     mBundle = new Bundle();
    167                     msg.data = mBundle;
    168                     msg.data.putString("key", "value");
    169 
    170                     Message newMsg = mHandler.obtainMessage();
    171                     newMsg.copyFrom(msg);
    172                     if (newMsg.isInUse() != false) {
    173                         failure(new RuntimeException(
    174                                 "newMsg.isInUse is true should be false after copyFrom"));
    175                     }
    176                     if (newMsg.flags != 0) {
    177                         failure(new RuntimeException(String.format(
    178                         "newMsg.flags is %d should be 0 after copyFrom", newMsg.flags)));
    179                     }
    180                     if (newMsg.what != 1) {
    181                         failure(new RuntimeException(String.format(
    182                                 "newMsg.what is %d should be %d after copyFrom", newMsg.what, 1)));
    183                     }
    184                     if (newMsg.arg1 != 456) {
    185                         failure(new RuntimeException(String.format(
    186                                 "newMsg.arg1 is %d should be %d after copyFrom", msg.arg1, 456)));
    187                     }
    188                     if (newMsg.arg2 != 789) {
    189                         failure(new RuntimeException(String.format(
    190                                 "newMsg.arg2 is %d should be %d after copyFrom", msg.arg2, 789)));
    191                     }
    192                     if (newMsg.obj != this) {
    193                         failure(new RuntimeException(
    194                                 "newMsg.obj should be 'this' after copyFrom"));
    195                     }
    196                     if (newMsg.replyTo != null) {
    197                         failure(new RuntimeException(
    198                                 "newMsg.replyTo should be null after copyFrom"));
    199                     }
    200                     if (newMsg.data == mBundle) {
    201                         failure(new RuntimeException(
    202                                 "newMsg.data should NOT be mBundle after copyFrom"));
    203                     }
    204                     if (!newMsg.data.getString("key").equals(mBundle.getString("key"))) {
    205                         failure(new RuntimeException(String.format(
    206                                 "newMsg.data.getString(\"key\") is %s and does not equal" +
    207                                 " mBundle.getString(\"key\") which is %s after copyFrom",
    208                                 newMsg.data.getString("key"),  mBundle.getString("key"))));
    209                     }
    210                     if (newMsg.when != 0) {
    211                         failure(new RuntimeException(String.format(
    212                                 "newMsg.when is %d should be 0 after copyFrom", newMsg.when)));
    213                     }
    214                     if (newMsg.target != mHandler) {
    215                         failure(new RuntimeException(
    216                                 "newMsg.target is NOT mHandler after copyFrom"));
    217                     }
    218                     if (newMsg.callback != null) {
    219                         failure(new RuntimeException(
    220                                 "newMsg.callback is NOT null after copyFrom"));
    221                     }
    222 
    223                     mHandler.sendMessage(newMsg);
    224                 } else if (msg.what == 1) {
    225                     if (msg.isInUse() != true) {
    226                         failure(new RuntimeException(String.format(
    227                                 "msg.isInUse is false should be true after when processing %d",
    228                                 msg.what)));
    229                     }
    230                     if (msg.arg1 != 456) {
    231                         failure(new RuntimeException(String.format(
    232                                 "msg.arg1 is %d should be %d when processing # %d",
    233                                 msg.arg1, 456, msg.what)));
    234                     }
    235                     if (msg.arg2 != 789) {
    236                         failure(new RuntimeException(String.format(
    237                                 "msg.arg2 is %d should be %d when processing # %d",
    238                                 msg.arg2, 789, msg.what)));
    239                     }
    240                     if (msg.obj != this) {
    241                         failure(new RuntimeException(String.format(
    242                                 "msg.obj should be 'this' when processing # %d", msg.what)));
    243                     }
    244                     if (msg.replyTo != null) {
    245                         failure(new RuntimeException(String.format(
    246                                 "msg.replyTo should be null when processing # %d", msg.what)));
    247                     }
    248                     if (!msg.data.getString("key").equals(mBundle.getString("key"))) {
    249                         failure(new RuntimeException(String.format(
    250                                 "msg.data.getString(\"key\") is %s and does not equal" +
    251                                 " mBundle.getString(\"key\") which is %s when processing # %d",
    252                                 msg.data.getString("key"),  mBundle.getString("key"), msg.what)));
    253                     }
    254                     if (msg.when != 0) {
    255                         failure(new RuntimeException(String.format(
    256                                 "msg.when is %d should be 0 when processing # %d",
    257                                 msg.when, msg.what)));
    258                     }
    259                     if (msg.target != null) {
    260                         failure(new RuntimeException(String.format(
    261                                 "msg.target is NOT null when processing # %d", msg.what)));
    262                     }
    263                     if (msg.callback != null) {
    264                         failure(new RuntimeException(String.format(
    265                                 "msg.callback is NOT null when processing # %d", msg.what)));
    266                     }
    267                 } else {
    268                     failure(new RuntimeException(String.format(
    269                             "Unexpected msg.what is %d" + msg.what)));
    270                 }
    271             }
    272         };
    273 
    274         tester.doTest(1000);
    275     }
    276 }
    277