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