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.app.stubs; 18 19 import android.app.Activity; 20 import android.content.BroadcastReceiver; 21 import android.content.ComponentName; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.content.IntentFilter; 25 import android.os.Binder; 26 import android.os.Bundle; 27 import android.os.Handler; 28 import android.os.IBinder; 29 import android.os.Message; 30 import android.os.Parcel; 31 import android.os.Parcelable; 32 import android.test.PerformanceTestCase; 33 import android.util.Log; 34 35 import java.util.ArrayList; 36 import java.util.HashMap; 37 import java.util.List; 38 import java.util.Map; 39 40 class MyBadParcelable implements Parcelable { MyBadParcelable()41 public MyBadParcelable() { 42 } 43 writeToParcel(Parcel out, int flags)44 public void writeToParcel(Parcel out, int flags) { 45 out.writeString("I am bad"); 46 } 47 describeContents()48 public int describeContents() { 49 return 0; 50 } 51 52 public static final Parcelable.Creator<MyBadParcelable> CREATOR = 53 new Parcelable.Creator<MyBadParcelable>() { 54 public MyBadParcelable createFromParcel(Parcel in) { 55 return new MyBadParcelable(in); 56 } 57 58 public MyBadParcelable[] newArray(int size) { 59 return new MyBadParcelable[size]; 60 } 61 }; 62 MyBadParcelable(Parcel in)63 public MyBadParcelable(Parcel in) { 64 in.readString(); 65 } 66 } 67 68 public class LaunchpadActivity extends Activity { 69 public interface CallingTest extends PerformanceTestCase.Intermediates { startTiming(boolean realTime)70 void startTiming(boolean realTime); 71 addIntermediate(String name)72 void addIntermediate(String name); 73 addIntermediate(String name, long timeInNS)74 void addIntermediate(String name, long timeInNS); 75 finishTiming(boolean realTime)76 void finishTiming(boolean realTime); 77 activityRunning(Activity activity)78 void activityRunning(Activity activity); 79 activityFinished(int resultCode, Intent data, RuntimeException where)80 void activityFinished(int resultCode, Intent data, RuntimeException where); 81 } 82 83 // Also used as the Binder interface descriptor string in these tests 84 public static final String LAUNCH = "android.app.cts.activity.LAUNCH"; 85 86 public static final String FORWARD_RESULT = "android.app.cts.activity.FORWARD_RESULT"; 87 public static final String RETURNED_RESULT = "android.app.cts.activity.RETURNED_RESULT"; 88 89 public static final String BAD_PARCELABLE = "android.app.cts.activity.BAD_PARCELABLE"; 90 91 public static final int LAUNCHED_RESULT = 1; 92 public static final int FORWARDED_RESULT = 2; 93 94 public static final String LIFECYCLE_BASIC = "android.app.cts.activity.LIFECYCLE_BASIC"; 95 public static final String LIFECYCLE_SCREEN = "android.app.cts.activity.LIFECYCLE_SCREEN"; 96 public static final String LIFECYCLE_DIALOG = "android.app.cts.activity.LIFECYCLE_DIALOG"; 97 98 public static final String ACTIVITY_PREPARE = "android.app.cts.activity.ACTIVITY_PREPARE"; 99 100 public static final String BROADCAST_REGISTERED = "android.app.cts.activity.BROADCAST_REGISTERED"; 101 public static final String BROADCAST_LOCAL = "android.app.cts.activity.BROADCAST_LOCAL"; 102 public static final String BROADCAST_REMOTE = "android.app.cts.activity.BROADCAST_REMOTE"; 103 public static final String BROADCAST_ALL = "android.app.cts.activity.BROADCAST_ALL"; 104 public static final String BROADCAST_REPEAT = "android.app.cts.activity.BROADCAST_REPEAT"; 105 public static final String BROADCAST_MULTI = "android.app.cts.activity.BROADCAST_MULTI"; 106 public static final String BROADCAST_ABORT = "android.app.cts.activity.BROADCAST_ABORT"; 107 108 public static final String EXPANDLIST_VIEW = "EXPANDLIST_VIEW"; 109 public static final String EXPANDLIST_CALLBACK = "EXPANDLIST_CALLBACK"; 110 111 public static final String BROADCAST_STICKY1 = "android.app.cts.activity.BROADCAST_STICKY1"; 112 public static final String BROADCAST_STICKY2 = "android.app.cts.activity.BROADCAST_STICKY2"; 113 114 public static final String ALIAS_ACTIVITY = "android.app.cts.activity.ALIAS_ACTIVITY"; 115 116 public static final String RECEIVER_REG = "receiver-reg"; 117 public static final String RECEIVER_LOCAL = "receiver-local"; 118 public static final String RECEIVER_REMOTE = "receiver-remote"; 119 public static final String RECEIVER_ABORT = "receiver-abort"; 120 121 public static final String DATA_1 = "one"; 122 public static final String DATA_2 = "two"; 123 124 public static final String ON_START = "onStart"; 125 public static final String ON_RESTART = "onRestart"; 126 public static final String ON_RESUME = "onResume"; 127 public static final String ON_FREEZE = "onSaveInstanceState"; 128 public static final String ON_PAUSE = "onPause"; 129 130 // ON_STOP and ON_DESTROY are not tested because they may not be called. 131 132 public static final String DO_FINISH = "finish"; 133 public static final String DO_LOCAL_SCREEN = "local-screen"; 134 public static final String DO_LOCAL_DIALOG = "local-dialog"; 135 136 private static final String TAG = "LaunchpadActivity"; 137 138 private boolean mBadParcelable = false; 139 140 private boolean mStarted = false; 141 142 private int mResultCode = RESULT_CANCELED; 143 private Intent mData = new Intent().setAction("No result received"); 144 private RuntimeException mResultStack = null; 145 146 /** Index into the {@link #mNextLifecycle} array. */ 147 private int mNextLifecycle; 148 149 /** Current lifecycle expected to be followed. */ 150 private String[] mExpectedLifecycle; 151 152 /** Other possible lifecycles. Never includes the current {@link #mExpectedLifecycle}. */ 153 private List<String[]> mOtherPossibleLifecycles = new ArrayList<String[]>(2); 154 155 /** Map from lifecycle arrays to debugging log names. */ 156 private Map<String[], String> mLifecycleNames = new HashMap<String[], String>(2); 157 158 private String[] mExpectedReceivers = null; 159 private int mNextReceiver; 160 161 private String[] mExpectedData = null; 162 private boolean[] mReceivedData = null; 163 164 boolean mReceiverRegistered = false; 165 166 private static CallingTest sCallingTest = null; 167 setCallingTest(CallingTest ct)168 public static void setCallingTest(CallingTest ct) { 169 sCallingTest = ct; 170 } 171 172 @Override onCreate(Bundle icicle)173 protected void onCreate(Bundle icicle) { 174 super.onCreate(icicle); 175 176 resetLifecycles(); 177 178 // ON_STOP and ON_DESTROY are not tested because they may not be called. 179 180 final String action = getIntent().getAction(); 181 if (LIFECYCLE_BASIC.equals(action)) { 182 addPossibleLifecycle(LIFECYCLE_BASIC, new String[] { 183 ON_START, ON_RESUME, DO_FINISH, ON_PAUSE 184 }); 185 } else if (LIFECYCLE_SCREEN.equals(action)) { 186 addPossibleLifecycle(LIFECYCLE_SCREEN + "_RESTART", new String[] { 187 ON_START, ON_RESUME, DO_LOCAL_SCREEN, ON_PAUSE, 188 ON_RESTART, ON_START, ON_RESUME, DO_FINISH, ON_PAUSE 189 }); 190 addPossibleLifecycle(LIFECYCLE_SCREEN + "_RESUME", new String[] { 191 ON_START, ON_RESUME, DO_LOCAL_SCREEN, ON_PAUSE, 192 ON_RESUME, DO_FINISH, ON_PAUSE 193 }); 194 } else if (LIFECYCLE_DIALOG.equals(action)) { 195 addPossibleLifecycle(LIFECYCLE_DIALOG + "_RESTART", new String[] { 196 ON_START, ON_RESUME, DO_LOCAL_DIALOG, ON_PAUSE, 197 ON_RESTART, ON_START, ON_RESUME, DO_FINISH, ON_PAUSE 198 }); 199 addPossibleLifecycle(LIFECYCLE_DIALOG + "_RESUME", new String[] { 200 ON_START, ON_RESUME, DO_LOCAL_DIALOG, ON_PAUSE, 201 ON_RESUME, DO_FINISH, ON_PAUSE 202 }); 203 } 204 } 205 resetLifecycles()206 private void resetLifecycles() { 207 mNextLifecycle = 0; 208 mExpectedLifecycle = null; 209 mOtherPossibleLifecycles.clear(); 210 mLifecycleNames.clear(); 211 } 212 213 /** 214 * Add a potential lifecycle that this activity may follow, since there 215 * are usually multiple valid lifecycles. For instance, sometimes onPause 216 * will lead to onResume rather than onStop when another activity is 217 * raised over the current one. 218 * 219 * @param debugName for the lifecycle shown in the logs 220 * @param lifecycle array containing tokens indicating the expected lifecycle 221 */ addPossibleLifecycle(String debugName, String[] lifecycle)222 private void addPossibleLifecycle(String debugName, String[] lifecycle) { 223 mLifecycleNames.put(lifecycle, debugName); 224 if (mExpectedLifecycle == null) { 225 mExpectedLifecycle = lifecycle; 226 } else { 227 mOtherPossibleLifecycles.add(lifecycle); 228 } 229 } 230 231 /** 232 * Switch to the next possible lifecycle and return if switching was 233 * successful. Call this method when mExpectedLifecycle doesn't match 234 * the current lifecycle and you need to check another possible lifecycle. 235 * 236 * @return whether on not there was a lifecycle to switch to 237 */ switchToNextPossibleLifecycle()238 private boolean switchToNextPossibleLifecycle() { 239 if (!mOtherPossibleLifecycles.isEmpty()) { 240 String[] newLifecycle = mOtherPossibleLifecycles.remove(0); 241 Log.w(TAG, "Switching expected lifecycles from " 242 + mLifecycleNames.get(mExpectedLifecycle) + " to " 243 + mLifecycleNames.get(newLifecycle)); 244 mExpectedLifecycle = newLifecycle; 245 return true; 246 } else { 247 Log.w(TAG, "No more lifecycles after " 248 + mLifecycleNames.get(mExpectedLifecycle)); 249 mExpectedLifecycle = null; 250 return false; 251 } 252 } 253 254 @Override onStart()255 protected void onStart() { 256 super.onStart(); 257 checkLifecycle(ON_START); 258 } 259 260 @Override onRestart()261 protected void onRestart() { 262 super.onStart(); 263 checkLifecycle(ON_RESTART); 264 } 265 266 @Override onResume()267 protected void onResume() { 268 super.onResume(); 269 270 checkLifecycle(ON_RESUME); 271 272 if (!mStarted) { 273 mStarted = true; 274 275 mHandler.postDelayed(mTimeout, 10 * 1000); 276 277 final String action = getIntent().getAction(); 278 279 sCallingTest.startTiming(true); 280 281 if (LAUNCH.equals(action)) { 282 final Intent intent = getIntent(); 283 intent.setFlags(0); 284 intent.setComponent((ComponentName) intent.getParcelableExtra("component")); 285 startActivityForResult(intent, LAUNCHED_RESULT); 286 } else if (ACTIVITY_PREPARE.equals(action)) { 287 sCallingTest.activityRunning(this); 288 } else if (FORWARD_RESULT.equals(action)) { 289 final Intent intent = getIntent(); 290 intent.setFlags(0); 291 intent.setClass(this, LocalScreen.class); 292 startActivityForResult(intent, FORWARDED_RESULT); 293 } else if (BAD_PARCELABLE.equals(action)) { 294 mBadParcelable = true; 295 final Intent intent = getIntent(); 296 intent.setFlags(0); 297 intent.setClass(this, LocalScreen.class); 298 startActivityForResult(intent, LAUNCHED_RESULT); 299 } else if (BROADCAST_REGISTERED.equals(action)) { 300 setExpectedReceivers(new String[] { 301 RECEIVER_REG 302 }); 303 registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED)); 304 sCallingTest.addIntermediate("after-register"); 305 sendBroadcast(makeBroadcastIntent(BROADCAST_REGISTERED)); 306 } else if (BROADCAST_LOCAL.equals(action)) { 307 setExpectedReceivers(new String[] { 308 RECEIVER_LOCAL 309 }); 310 sendBroadcast(makeBroadcastIntent(BROADCAST_LOCAL)); 311 } else if (BROADCAST_REMOTE.equals(action)) { 312 setExpectedReceivers(new String[] { 313 RECEIVER_REMOTE 314 }); 315 sendBroadcast(makeBroadcastIntent(BROADCAST_REMOTE)); 316 } else if (BROADCAST_ALL.equals(action)) { 317 setExpectedReceivers(new String[] { 318 RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL 319 }); 320 registerMyReceiver(new IntentFilter(BROADCAST_ALL)); 321 sCallingTest.addIntermediate("after-register"); 322 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null); 323 } else if (BROADCAST_MULTI.equals(action)) { 324 setExpectedReceivers(new String[] { 325 RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL, RECEIVER_REMOTE, 326 RECEIVER_REG, RECEIVER_LOCAL, RECEIVER_REMOTE, RECEIVER_REG, 327 RECEIVER_LOCAL, RECEIVER_LOCAL, RECEIVER_REMOTE, RECEIVER_LOCAL, 328 RECEIVER_REMOTE, RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL, 329 RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL, RECEIVER_REMOTE, 330 RECEIVER_REG, RECEIVER_LOCAL, RECEIVER_REMOTE, RECEIVER_LOCAL, 331 RECEIVER_REMOTE, RECEIVER_LOCAL 332 }); 333 registerMyReceiver(new IntentFilter(BROADCAST_ALL)); 334 sCallingTest.addIntermediate("after-register"); 335 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null); 336 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null); 337 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null); 338 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_LOCAL), null); 339 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REMOTE), null); 340 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_LOCAL), null); 341 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REMOTE), null); 342 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null); 343 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null); 344 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null); 345 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REPEAT), null); 346 } else if (BROADCAST_ABORT.equals(action)) { 347 setExpectedReceivers(new String[] { 348 RECEIVER_REMOTE, RECEIVER_ABORT 349 }); 350 registerMyReceiver(new IntentFilter(BROADCAST_ABORT)); 351 sCallingTest.addIntermediate("after-register"); 352 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ABORT), null); 353 } else if (BROADCAST_STICKY1.equals(action)) { 354 setExpectedReceivers(new String[] { 355 RECEIVER_REG 356 }); 357 setExpectedData(new String[] { 358 DATA_1 359 }); 360 registerMyReceiver(new IntentFilter(BROADCAST_STICKY1)); 361 sCallingTest.addIntermediate("after-register"); 362 } else if (BROADCAST_STICKY2.equals(action)) { 363 setExpectedReceivers(new String[] { 364 RECEIVER_REG, RECEIVER_REG 365 }); 366 setExpectedData(new String[] { 367 DATA_1, DATA_2 368 }); 369 final IntentFilter filter = new IntentFilter(BROADCAST_STICKY1); 370 filter.addAction(BROADCAST_STICKY2); 371 registerMyReceiver(filter); 372 sCallingTest.addIntermediate("after-register"); 373 } else if (ALIAS_ACTIVITY.equals(action)) { 374 final Intent intent = getIntent(); 375 intent.setFlags(0); 376 intent.setClass(this, AliasActivityStub.class); 377 startActivityForResult(intent, LAUNCHED_RESULT); 378 } else if (EXPANDLIST_VIEW.equals(action)) { 379 final Intent intent = getIntent(); 380 intent.setFlags(0); 381 intent.setAction(action); 382 intent.setComponent((ComponentName) intent.getParcelableExtra("component")); 383 startActivityForResult(intent, LAUNCHED_RESULT); 384 } else if (EXPANDLIST_CALLBACK.equals(action)) { 385 final Intent intent = getIntent(); 386 intent.setFlags(0); 387 intent.setAction(action); 388 intent.setComponent((ComponentName) intent.getParcelableExtra("component")); 389 startActivityForResult(intent, LAUNCHED_RESULT); 390 } 391 } 392 } 393 394 @Override onSaveInstanceState(Bundle icicle)395 protected void onSaveInstanceState(Bundle icicle) { 396 super.onSaveInstanceState(icicle); 397 if (mBadParcelable) { 398 icicle.putParcelable("baddy", new MyBadParcelable()); 399 } 400 } 401 402 @Override onPause()403 protected void onPause() { 404 super.onPause(); 405 checkLifecycle(ON_PAUSE); 406 } 407 408 @Override onActivityResult(int requestCode, int resultCode, Intent data)409 protected void onActivityResult(int requestCode, int resultCode, Intent data) { 410 switch (requestCode) { 411 case LAUNCHED_RESULT: 412 sCallingTest.finishTiming(true); 413 finishWithResult(resultCode, data); 414 break; 415 case FORWARDED_RESULT: 416 sCallingTest.finishTiming(true); 417 if (RETURNED_RESULT.equals(data.getAction())) { 418 finishWithResult(resultCode, data); 419 } else { 420 finishWithResult(RESULT_CANCELED, new Intent().setAction("Bad data returned: " 421 + data)); 422 } 423 break; 424 default: 425 sCallingTest.finishTiming(true); 426 finishWithResult(RESULT_CANCELED, new Intent() 427 .setAction("Unexpected request code: " + requestCode)); 428 break; 429 } 430 } 431 checkLifecycle(String where)432 private void checkLifecycle(String where) { 433 String action = getIntent().getAction(); 434 435 if (mExpectedLifecycle == null) { 436 return; 437 } 438 439 if (mNextLifecycle >= mExpectedLifecycle.length) { 440 finishBad("Activity lifecycle for " + action + " incorrect: received " + where 441 + " but don't expect any more calls"); 442 mExpectedLifecycle = null; 443 return; 444 } 445 446 do { 447 if (mExpectedLifecycle[mNextLifecycle].equals(where)) { 448 Log.w(TAG, "Matched: " + where); 449 break; 450 } else { 451 Log.w(TAG, "Expected " + mExpectedLifecycle[mNextLifecycle] + " but got " + where); 452 } 453 } while (switchToNextPossibleLifecycle()); 454 455 if (mExpectedLifecycle == null) { 456 finishBad("Activity lifecycle for " + action + " incorrect: received " + where 457 + " at " + mNextLifecycle); 458 return; 459 } 460 461 mNextLifecycle++; 462 463 if (mNextLifecycle >= mExpectedLifecycle.length) { 464 finishGood(); 465 return; 466 } 467 468 final String next = mExpectedLifecycle[mNextLifecycle]; 469 if (next.equals(DO_FINISH)) { 470 mNextLifecycle++; 471 if (mNextLifecycle >= mExpectedLifecycle.length) { 472 setTestResult(RESULT_OK, null); 473 } 474 if (!isFinishing()) { 475 finish(); 476 } 477 } else if (next.equals(DO_LOCAL_SCREEN)) { 478 mNextLifecycle++; 479 final Intent intent = new Intent(TestedScreen.WAIT_BEFORE_FINISH); 480 intent.setClass(this, LocalScreen.class); 481 startActivity(intent); 482 } else if (next.equals(DO_LOCAL_DIALOG)) { 483 mNextLifecycle++; 484 final Intent intent = new Intent(TestedScreen.WAIT_BEFORE_FINISH); 485 intent.setClass(this, LocalDialog.class); 486 startActivity(intent); 487 } 488 } 489 setExpectedReceivers(String[] receivers)490 private void setExpectedReceivers(String[] receivers) { 491 mExpectedReceivers = receivers; 492 mNextReceiver = 0; 493 } 494 setExpectedData(String[] data)495 private void setExpectedData(String[] data) { 496 mExpectedData = data; 497 mReceivedData = new boolean[data.length]; 498 } 499 500 @SuppressWarnings("deprecation") makeBroadcastIntent(String action)501 private Intent makeBroadcastIntent(String action) { 502 final Intent intent = new Intent(action, null); 503 intent.putExtra("caller", mCallTarget); 504 return intent; 505 } 506 finishGood()507 private void finishGood() { 508 finishWithResult(RESULT_OK, null); 509 } 510 finishBad(String error)511 private void finishBad(String error) { 512 finishWithResult(RESULT_CANCELED, new Intent().setAction(error)); 513 } 514 finishWithResult(int resultCode, Intent data)515 private void finishWithResult(int resultCode, Intent data) { 516 setTestResult(resultCode, data); 517 finish(); 518 519 // Member fields set by calling setTestResult above... 520 sCallingTest.activityFinished(mResultCode, mData, mResultStack); 521 } 522 setTestResult(int resultCode, Intent data)523 private void setTestResult(int resultCode, Intent data) { 524 mHandler.removeCallbacks(mTimeout); 525 unregisterMyReceiver(); 526 mResultCode = resultCode; 527 mData = data; 528 mResultStack = new RuntimeException("Original error was here"); 529 mResultStack.fillInStackTrace(); 530 } 531 registerMyReceiver(IntentFilter filter)532 private void registerMyReceiver(IntentFilter filter) { 533 mReceiverRegistered = true; 534 registerReceiver(mReceiver, filter); 535 } 536 unregisterMyReceiver()537 private void unregisterMyReceiver() { 538 if (mReceiverRegistered) { 539 mReceiverRegistered = false; 540 unregisterReceiver(mReceiver); 541 } 542 } 543 544 private final Handler mHandler = new Handler() { 545 @Override 546 public void handleMessage(Message msg) { 547 } 548 }; 549 550 static final int GOT_RECEIVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION; 551 static final int ERROR_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 1; 552 553 private final Binder mCallTarget = new Binder() { 554 @Override 555 public boolean onTransact(int code, Parcel data, Parcel reply, int flags) { 556 data.setDataPosition(0); 557 data.enforceInterface(LaunchpadActivity.LAUNCH); 558 if (code == GOT_RECEIVE_TRANSACTION) { 559 final String name = data.readString(); 560 gotReceive(name, null); 561 return true; 562 } else if (code == ERROR_TRANSACTION) { 563 finishBad(data.readString()); 564 return true; 565 } 566 return false; 567 } 568 }; 569 gotReceive(String name, Intent intent)570 private final void gotReceive(String name, Intent intent) { 571 synchronized (this) { 572 573 sCallingTest.addIntermediate(mNextReceiver + "-" + name); 574 575 if (mExpectedData != null) { 576 final int n = mExpectedData.length; 577 int i; 578 boolean prev = false; 579 for (i = 0; i < n; i++) { 580 if (mExpectedData[i].equals(intent.getStringExtra("test"))) { 581 if (mReceivedData[i]) { 582 prev = true; 583 continue; 584 } 585 mReceivedData[i] = true; 586 break; 587 } 588 } 589 if (i >= n) { 590 if (prev) { 591 finishBad("Receive got data too many times: " 592 + intent.getStringExtra("test")); 593 } else { 594 finishBad("Receive got unexpected data: " + intent.getStringExtra("test")); 595 } 596 return; 597 } 598 } 599 600 if (mNextReceiver >= mExpectedReceivers.length) { 601 finishBad("Got too many onReceiveIntent() calls!"); 602 } else if (!mExpectedReceivers[mNextReceiver].equals(name)) { 603 finishBad("Receive out of order: got " + name + " but expected " 604 + mExpectedReceivers[mNextReceiver] + " at " + mNextReceiver); 605 } else { 606 mNextReceiver++; 607 if (mNextReceiver == mExpectedReceivers.length) { 608 mHandler.post(mUnregister); 609 } 610 } 611 612 } 613 } 614 615 private final Runnable mUnregister = new Runnable() { 616 public void run() { 617 if (mReceiverRegistered) { 618 sCallingTest.addIntermediate("before-unregister"); 619 unregisterMyReceiver(); 620 } 621 sCallingTest.finishTiming(true); 622 finishGood(); 623 } 624 }; 625 626 private final Runnable mTimeout = new Runnable() { 627 public void run() { 628 Log.i(TAG, "timeout"); 629 String msg = "Timeout"; 630 if (mExpectedReceivers != null && mNextReceiver < mExpectedReceivers.length) { 631 msg = msg + " waiting for " + mExpectedReceivers[mNextReceiver]; 632 } 633 finishBad(msg); 634 } 635 }; 636 637 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 638 @Override 639 public void onReceive(Context context, Intent intent) { 640 gotReceive(RECEIVER_REG, intent); 641 } 642 }; 643 } 644