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 17package android.os; 18 19import android.os.Handler; 20import android.os.Message; 21import android.os.SystemClock; 22import android.test.suitebuilder.annotation.MediumTest; 23import junit.framework.TestCase; 24 25public 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