Home | History | Annotate | Download | only in activity
      1 /*
      2  * Copyright (C) 2006 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.activity;
     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 class MyBadParcelable implements Parcelable {
     36     public MyBadParcelable() {
     37     }
     38 
     39     public void writeToParcel(Parcel out, int flags) {
     40         out.writeString("I am bad");
     41     }
     42 
     43     public int describeContents() {
     44         return 0;
     45     }
     46 
     47     public static final Parcelable.Creator<MyBadParcelable> CREATOR
     48             = new Parcelable.Creator<MyBadParcelable>() {
     49         public MyBadParcelable createFromParcel(Parcel in) {
     50             return new MyBadParcelable(in);
     51         }
     52 
     53         public MyBadParcelable[] newArray(int size) {
     54             return new MyBadParcelable[size];
     55         }
     56     };
     57 
     58     public MyBadParcelable(Parcel in) {
     59         String nm = in.readString();
     60     }
     61 }
     62 
     63 public class LaunchpadActivity extends Activity {
     64     public interface CallingTest extends PerformanceTestCase.Intermediates {
     65         public void startTiming(boolean realTime);
     66         public void addIntermediate(String name);
     67         public void addIntermediate(String name, long timeInNS);
     68         public void finishTiming(boolean realTime);
     69         public void activityFinished(int resultCode, Intent data,
     70                 RuntimeException where);
     71     }
     72 
     73     // Also used as the Binder interface descriptor string in these tests
     74     public static final String LAUNCH = "com.android.frameworks.coretests.activity.LAUNCH";
     75 
     76     public static final String FORWARD_RESULT =
     77             "com.android.frameworks.coretests.activity.FORWARD_RESULT";
     78     public static final String RETURNED_RESULT =
     79             "com.android.frameworks.coretests.activity.RETURNED_RESULT";
     80 
     81     public static final String BAD_PARCELABLE =
     82             "comcom.android.frameworks.coretests.activity.BAD_PARCELABLE";
     83 
     84     public static final int LAUNCHED_RESULT = 1;
     85     public static final int FORWARDED_RESULT = 2;
     86 
     87     public static final String LIFECYCLE_BASIC =
     88             "com.android.frameworks.coretests.activity.LIFECYCLE_BASIC";
     89     public static final String LIFECYCLE_SCREEN =
     90             "com.android.frameworks.coretests.activity.LIFECYCLE_SCREEN";
     91     public static final String LIFECYCLE_DIALOG =
     92             "com.android.frameworks.coretests.activity.LIFECYCLE_DIALOG";
     93     public static final String LIFECYCLE_FINISH_CREATE =
     94             "com.android.frameworks.coretests.activity.LIFECYCLE_FINISH_CREATE";
     95     public static final String LIFECYCLE_FINISH_START =
     96             "com.android.frameworks.coretests.activity.LIFECYCLE_FINISH_START";
     97 
     98     public static final String BROADCAST_REGISTERED =
     99             "com.android.frameworks.coretests.activity.BROADCAST_REGISTERED";
    100     public static final String BROADCAST_LOCAL =
    101             "com.android.frameworks.coretests.activity.BROADCAST_LOCAL";
    102     public static final String BROADCAST_REMOTE =
    103             "com.android.frameworks.coretests.activity.BROADCAST_REMOTE";
    104     public static final String BROADCAST_ALL =
    105             "com.android.frameworks.coretests.activity.BROADCAST_ALL";
    106     public static final String BROADCAST_REPEAT =
    107         "com.android.frameworks.coretests.activity.BROADCAST_REPEAT";
    108     public static final String BROADCAST_MULTI =
    109             "com.android.frameworks.coretests.activity.BROADCAST_MULTI";
    110     public static final String BROADCAST_ABORT =
    111             "com.android.frameworks.coretests.activity.BROADCAST_ABORT";
    112 
    113     public static final String BROADCAST_STICKY1 =
    114             "com.android.frameworks.coretests.activity.BROADCAST_STICKY1";
    115     public static final String BROADCAST_STICKY2 =
    116             "com.android.frameworks.coretests.activity.BROADCAST_STICKY2";
    117 
    118     public static final String RECEIVER_REG = "receiver-reg";
    119     public static final String RECEIVER_LOCAL = "receiver-local";
    120     public static final String RECEIVER_REMOTE = "receiver-remote";
    121     public static final String RECEIVER_ABORT = "receiver-abort";
    122 
    123     public static final String DATA_1 = "one";
    124     public static final String DATA_2 = "two";
    125 
    126     public static final String ON_START = "onStart";
    127     public static final String ON_RESTART = "onRestart";
    128     public static final String ON_RESUME = "onResume";
    129     public static final String ON_FREEZE = "onSaveInstanceState";
    130     public static final String ON_PAUSE = "onPause";
    131     public static final String ON_STOP = "onStop";
    132     public static final String ON_DESTROY = "onDestroy";
    133 
    134     public static final String DO_FINISH = "finish";
    135     public static final String DO_LOCAL_SCREEN = "local-screen";
    136     public static final String DO_LOCAL_DIALOG = "local-dialog";
    137 
    138     private boolean mBadParcelable = false;
    139 
    140     private boolean mStarted = false;
    141     private long mStartTime;
    142 
    143     private int mResultCode = RESULT_CANCELED;
    144     private Intent mData = (new Intent()).setAction("No result received");
    145     private RuntimeException mResultStack = null;
    146 
    147     private String[] mExpectedLifecycle = null;
    148     private int mNextLifecycle;
    149 
    150     private String[] mExpectedReceivers = null;
    151     private int mNextReceiver;
    152 
    153     private String[] mExpectedData = null;
    154     private boolean[] mReceivedData = null;
    155 
    156     boolean mReceiverRegistered = false;
    157 
    158     private static CallingTest sCallingTest = null;
    159 
    160     public static void setCallingTest(CallingTest ct) {
    161         sCallingTest = ct;
    162     }
    163 
    164     public LaunchpadActivity() {
    165         mStartTime = System.currentTimeMillis();
    166     }
    167 
    168     @Override
    169     protected void onCreate(Bundle icicle) {
    170         super.onCreate(icicle);
    171         String action = getIntent().getAction();
    172         if (ActivityTests.DEBUG_LIFECYCLE) Log.v("test", "CREATE lauchpad "
    173                 + Integer.toHexString(System.identityHashCode(this)) + ": " + getIntent());
    174         if (LIFECYCLE_BASIC.equals(action)) {
    175             setExpectedLifecycle(new String[]{ON_START, ON_RESUME,
    176                     DO_FINISH, ON_PAUSE, ON_STOP, ON_DESTROY});
    177         } else if (LIFECYCLE_SCREEN.equals(action)) {
    178             setExpectedLifecycle(new String[]{ON_START, ON_RESUME,
    179                     DO_LOCAL_SCREEN, ON_FREEZE, ON_PAUSE, ON_STOP,
    180                     ON_RESTART, ON_START, ON_RESUME,
    181                     DO_FINISH, ON_PAUSE, ON_STOP, ON_DESTROY});
    182         } else if (LIFECYCLE_DIALOG.equals(action)) {
    183             setExpectedLifecycle(new String[]{ON_START, ON_RESUME,
    184                     DO_LOCAL_DIALOG, ON_FREEZE, ON_PAUSE, ON_RESUME,
    185                     DO_FINISH, ON_PAUSE, ON_STOP, ON_DESTROY});
    186         } else if (LIFECYCLE_FINISH_CREATE.equals(action)) {
    187             // This one behaves a little differently when running in a group.
    188             if (getParent() == null) {
    189                 setExpectedLifecycle(new String[]{ON_DESTROY});
    190             } else {
    191                 setExpectedLifecycle(new String[]{ON_START, ON_STOP, ON_DESTROY});
    192             }
    193             finish();
    194         } else if (LIFECYCLE_FINISH_START.equals(action)) {
    195             setExpectedLifecycle(new String[]{ON_START, DO_FINISH,
    196                     ON_STOP, ON_DESTROY});
    197         }
    198     }
    199 
    200     @Override
    201     protected void onStart() {
    202         super.onStart();
    203         if (ActivityTests.DEBUG_LIFECYCLE) Log.v("test", "START lauchpad "
    204                 + Integer.toHexString(System.identityHashCode(this)) + ": " + getIntent());
    205         checkLifecycle(ON_START);
    206     }
    207 
    208     @Override
    209     protected void onRestart() {
    210         super.onStart();
    211         checkLifecycle(ON_RESTART);
    212     }
    213 
    214     @Override
    215     protected void onResume() {
    216         super.onResume();
    217 
    218         if (ActivityTests.DEBUG_LIFECYCLE) Log.v("test", "RESUME lauchpad "
    219                 + Integer.toHexString(System.identityHashCode(this)) + ": " + getIntent());
    220         checkLifecycle(ON_RESUME);
    221 
    222         if (!mStarted) {
    223             mStarted = true;
    224 
    225             mHandler.postDelayed(mTimeout, 5 * 1000);
    226 
    227             String action = getIntent().getAction();
    228 
    229             sCallingTest.startTiming(true);
    230 
    231             if (LAUNCH.equals(action)) {
    232                 Intent intent = getIntent();
    233                 intent.setFlags(0);
    234                 intent.setComponent((ComponentName)
    235                         intent.getParcelableExtra("component"));
    236                 //System.out.println("*** Launchpad is starting: comp=" + intent.component);
    237                 startActivityForResult(intent, LAUNCHED_RESULT);
    238             } else if (FORWARD_RESULT.equals(action)) {
    239                 Intent intent = getIntent();
    240                 intent.setFlags(0);
    241                 intent.setClass(this, LocalScreen.class);
    242                 startActivityForResult(intent, FORWARDED_RESULT);
    243             } else if (BAD_PARCELABLE.equals(action)) {
    244                 mBadParcelable = true;
    245                 Intent intent = getIntent();
    246                 intent.setFlags(0);
    247                 intent.setClass(this, LocalScreen.class);
    248                 startActivityForResult(intent, LAUNCHED_RESULT);
    249             } else if (BROADCAST_REGISTERED.equals(action)) {
    250                 setExpectedReceivers(new String[]{RECEIVER_REG});
    251                 registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED));
    252                 sCallingTest.addIntermediate("after-register");
    253                 sendBroadcast(makeBroadcastIntent(BROADCAST_REGISTERED));
    254             } else if (BROADCAST_LOCAL.equals(action)) {
    255                 setExpectedReceivers(new String[]{RECEIVER_LOCAL});
    256                 sendBroadcast(makeBroadcastIntent(BROADCAST_LOCAL));
    257             } else if (BROADCAST_REMOTE.equals(action)) {
    258                 setExpectedReceivers(new String[]{RECEIVER_REMOTE});
    259                 sendBroadcast(makeBroadcastIntent(BROADCAST_REMOTE));
    260             } else if (BROADCAST_ALL.equals(action)) {
    261                 setExpectedReceivers(new String[]{
    262                         RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL});
    263                 registerMyReceiver(new IntentFilter(BROADCAST_ALL));
    264                 sCallingTest.addIntermediate("after-register");
    265                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
    266             } else if (BROADCAST_MULTI.equals(action)) {
    267                 setExpectedReceivers(new String[]{
    268                         RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL,
    269                         RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL,
    270                         RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL,
    271                         RECEIVER_LOCAL, RECEIVER_REMOTE,
    272                         RECEIVER_LOCAL, RECEIVER_REMOTE,
    273                         RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL,
    274                         RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL,
    275                         RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL,
    276                         RECEIVER_REMOTE, RECEIVER_LOCAL,
    277                         RECEIVER_REMOTE, RECEIVER_LOCAL});
    278                 registerMyReceiver(new IntentFilter(BROADCAST_ALL));
    279                 sCallingTest.addIntermediate("after-register");
    280                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
    281                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
    282                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
    283                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_LOCAL), null);
    284                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REMOTE), null);
    285                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_LOCAL), null);
    286                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REMOTE), null);
    287                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
    288                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
    289                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
    290                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REPEAT), null);
    291             } else if (BROADCAST_ABORT.equals(action)) {
    292                 setExpectedReceivers(new String[]{
    293                         RECEIVER_REMOTE, RECEIVER_ABORT});
    294                 registerMyReceiver(new IntentFilter(BROADCAST_ABORT));
    295                 sCallingTest.addIntermediate("after-register");
    296                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ABORT), null);
    297             } else if (BROADCAST_STICKY1.equals(action)) {
    298                 setExpectedReceivers(new String[]{RECEIVER_REG});
    299                 setExpectedData(new String[]{DATA_1});
    300                 registerMyReceiver(new IntentFilter(BROADCAST_STICKY1));
    301                 sCallingTest.addIntermediate("after-register");
    302             } else if (BROADCAST_STICKY2.equals(action)) {
    303                 setExpectedReceivers(new String[]{RECEIVER_REG, RECEIVER_REG});
    304                 setExpectedData(new String[]{DATA_1, DATA_2});
    305                 IntentFilter filter = new IntentFilter(BROADCAST_STICKY1);
    306                 filter.addAction(BROADCAST_STICKY2);
    307                 registerMyReceiver(filter);
    308                 sCallingTest.addIntermediate("after-register");
    309             }
    310         }
    311     }
    312 
    313     @Override
    314     protected void onSaveInstanceState(Bundle icicle) {
    315         super.onSaveInstanceState(icicle);
    316         checkLifecycle(ON_FREEZE);
    317         if (mBadParcelable) {
    318             icicle.putParcelable("baddy", new MyBadParcelable());
    319         }
    320     }
    321 
    322     @Override
    323     protected void onPause() {
    324         super.onPause();
    325         if (ActivityTests.DEBUG_LIFECYCLE) Log.v("test", "PAUSE lauchpad "
    326                 + Integer.toHexString(System.identityHashCode(this)) + ": " + getIntent());
    327         checkLifecycle(ON_PAUSE);
    328     }
    329 
    330     @Override
    331     protected void onStop() {
    332         super.onStop();
    333         if (ActivityTests.DEBUG_LIFECYCLE) Log.v("test", "STOP lauchpad "
    334                 + Integer.toHexString(System.identityHashCode(this)) + ": " + getIntent());
    335         checkLifecycle(ON_STOP);
    336     }
    337 
    338     @Override
    339     protected void onActivityResult(int requestCode, int resultCode,
    340             Intent data) {
    341         switch (requestCode) {
    342             case LAUNCHED_RESULT:
    343                 sCallingTest.finishTiming(true);
    344                 finishWithResult(resultCode, data);
    345                 break;
    346             case FORWARDED_RESULT:
    347                 sCallingTest.finishTiming(true);
    348                 if (RETURNED_RESULT.equals(data.getAction())) {
    349                     finishWithResult(resultCode, data);
    350                 } else {
    351                     finishWithResult(RESULT_CANCELED, (new Intent()).setAction(
    352                             "Bad data returned: " + data));
    353                 }
    354                 break;
    355             default:
    356                 sCallingTest.finishTiming(true);
    357                 finishWithResult(RESULT_CANCELED, (new Intent()).setAction(
    358                         "Unexpected request code: " + requestCode));
    359                 break;
    360         }
    361     }
    362 
    363     @Override
    364     protected void onDestroy() {
    365         super.onDestroy();
    366         if (ActivityTests.DEBUG_LIFECYCLE) Log.v("test", "DESTROY lauchpad "
    367                 + Integer.toHexString(System.identityHashCode(this)) + ": " + getIntent());
    368         checkLifecycle(ON_DESTROY);
    369         sCallingTest.activityFinished(mResultCode, mData, mResultStack);
    370     }
    371 
    372     private void setExpectedLifecycle(String[] lifecycle) {
    373         mExpectedLifecycle = lifecycle;
    374         mNextLifecycle = 0;
    375     }
    376 
    377     private void checkLifecycle(String where) {
    378         if (mExpectedLifecycle == null) return;
    379 
    380         if (mNextLifecycle >= mExpectedLifecycle.length) {
    381             finishBad("Activity lifecycle incorrect: received " + where
    382                     + " but don't expect any more calls");
    383             mExpectedLifecycle = null;
    384             return;
    385         }
    386         if (!mExpectedLifecycle[mNextLifecycle].equals(where)) {
    387             finishBad("Activity lifecycle incorrect: received " + where
    388                     + " but expected " + mExpectedLifecycle[mNextLifecycle]
    389                     + " at " + mNextLifecycle);
    390             mExpectedLifecycle = null;
    391             return;
    392         }
    393 
    394         mNextLifecycle++;
    395 
    396         if (mNextLifecycle >= mExpectedLifecycle.length) {
    397             setTestResult(RESULT_OK, null);
    398             return;
    399         }
    400 
    401         String next = mExpectedLifecycle[mNextLifecycle];
    402         if (where.equals(ON_DESTROY)) {
    403             finishBad("Activity lifecycle incorrect: received " + where
    404                     + " but expected more actions (next is " + next + ")");
    405             mExpectedLifecycle = null;
    406             return;
    407         } else if (next.equals(DO_FINISH)) {
    408             mNextLifecycle++;
    409             if (mNextLifecycle >= mExpectedLifecycle.length) {
    410                 setTestResult(RESULT_OK, null);
    411             }
    412             if (!isFinishing()) {
    413                 finish();
    414             }
    415         } else if (next.equals(DO_LOCAL_SCREEN)) {
    416             mNextLifecycle++;
    417             Intent intent = new Intent(TestedScreen.WAIT_BEFORE_FINISH);
    418             intent.setClass(this, LocalScreen.class);
    419             startActivity(intent);
    420         } else if (next.equals(DO_LOCAL_DIALOG)) {
    421             mNextLifecycle++;
    422             Intent intent = new Intent(TestedScreen.WAIT_BEFORE_FINISH);
    423             intent.setClass(this, LocalDialog.class);
    424             startActivity(intent);
    425         }
    426     }
    427 
    428     private void setExpectedReceivers(String[] receivers) {
    429         mExpectedReceivers = receivers;
    430         mNextReceiver = 0;
    431     }
    432 
    433     private void setExpectedData(String[] data) {
    434         mExpectedData = data;
    435         mReceivedData = new boolean[data.length];
    436     }
    437 
    438     private Intent makeBroadcastIntent(String action) {
    439         Intent intent = new Intent(action, null);
    440         intent.putExtra("caller", mCallTarget);
    441         return intent;
    442     }
    443 
    444     private void finishGood() {
    445         finishWithResult(RESULT_OK, null);
    446     }
    447 
    448     private void finishBad(String error) {
    449         finishWithResult(RESULT_CANCELED, (new Intent()).setAction(error));
    450     }
    451 
    452     private void finishWithResult(int resultCode, Intent data) {
    453         setTestResult(resultCode, data);
    454         finish();
    455     }
    456 
    457     private void setTestResult(int resultCode, Intent data) {
    458         mHandler.removeCallbacks(mTimeout);
    459         unregisterMyReceiver();
    460         mResultCode = resultCode;
    461         mData = data;
    462         mResultStack = new RuntimeException("Original error was here");
    463         mResultStack.fillInStackTrace();
    464     }
    465 
    466     private void registerMyReceiver(IntentFilter filter) {
    467         mReceiverRegistered = true;
    468         //System.out.println("Registering: " + mReceiver);
    469         registerReceiver(mReceiver, filter);
    470     }
    471 
    472     private void unregisterMyReceiver() {
    473         if (mReceiverRegistered) {
    474             mReceiverRegistered = false;
    475             //System.out.println("Unregistering: " + mReceiver);
    476             unregisterReceiver(mReceiver);
    477         }
    478     }
    479 
    480     private Handler mHandler = new Handler() {
    481         public void handleMessage(Message msg) {
    482         }
    483     };
    484 
    485     static final int GOT_RECEIVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
    486     static final int ERROR_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 1;
    487 
    488     private Binder mCallTarget = new Binder() {
    489         public boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
    490             data.setDataPosition(0);
    491             data.enforceInterface(LaunchpadActivity.LAUNCH);
    492             if (code == GOT_RECEIVE_TRANSACTION) {
    493                 String name = data.readString();
    494                 gotReceive(name, null);
    495                 return true;
    496             } else if (code == ERROR_TRANSACTION) {
    497                 finishBad(data.readString());
    498                 return true;
    499             }
    500             return false;
    501         }
    502     };
    503 
    504     private final void gotReceive(String name, Intent intent) {
    505         synchronized (this) {
    506 
    507             //System.out.println("Got receive: " + name);
    508             //System.out.println(mNextReceiver + " in " + mExpectedReceivers);
    509             //new RuntimeException("stack").printStackTrace();
    510 
    511             sCallingTest.addIntermediate(mNextReceiver + "-" + name);
    512 
    513             if (mExpectedData != null) {
    514                 int n = mExpectedData.length;
    515                 int i;
    516                 boolean prev = false;
    517                 for (i = 0; i < n; i++) {
    518                     if (mExpectedData[i].equals(intent.getStringExtra("test"))) {
    519                         if (mReceivedData[i]) {
    520                             prev = true;
    521                             continue;
    522                         }
    523                         mReceivedData[i] = true;
    524                         break;
    525                     }
    526                 }
    527                 if (i >= n) {
    528                     if (prev) {
    529                         finishBad("Receive got data too many times: "
    530                                 + intent.getStringExtra("test"));
    531                     } else {
    532                         finishBad("Receive got unexpected data: "
    533                                 + intent.getStringExtra("test"));
    534                     }
    535                     return;
    536                 }
    537             }
    538 
    539             if (mNextReceiver >= mExpectedReceivers.length) {
    540                 finishBad("Got too many onReceiveIntent() calls!");
    541 //                System.out.println("Too many intents received: now at "
    542 //                                   + mNextReceiver + ", expect list: "
    543 //                                   + Arrays.toString(mExpectedReceivers));
    544             } else if (!mExpectedReceivers[mNextReceiver].equals(name)) {
    545                 finishBad("Receive out of order: got " + name + " but expected "
    546                         + mExpectedReceivers[mNextReceiver] + " at "
    547                         + mNextReceiver);
    548             } else {
    549                 mNextReceiver++;
    550                 if (mNextReceiver == mExpectedReceivers.length) {
    551                     mHandler.post(mUnregister);
    552                 }
    553             }
    554 
    555         }
    556     }
    557 
    558     private Runnable mUnregister = new Runnable() {
    559         public void run() {
    560             if (mReceiverRegistered) {
    561                 sCallingTest.addIntermediate("before-unregister");
    562                 unregisterMyReceiver();
    563             }
    564             sCallingTest.finishTiming(true);
    565             finishGood();
    566         }
    567     };
    568 
    569     private Runnable mTimeout = new Runnable() {
    570         public void run() {
    571             Log.i("foo", "**** TIMEOUT");
    572             String msg = "Timeout";
    573             if (mExpectedReceivers != null
    574                     && mNextReceiver < mExpectedReceivers.length) {
    575                 msg = msg + " waiting for " + mExpectedReceivers[mNextReceiver];
    576             }
    577             finishBad(msg);
    578         }
    579     };
    580 
    581     private BroadcastReceiver mReceiver = new BroadcastReceiver() {
    582         public void onReceive(Context context, Intent intent) {
    583             //System.out.println("Receive in: " + this + ": " + intent);
    584             gotReceive(RECEIVER_REG, intent);
    585         }
    586     };
    587 }
    588 
    589