• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
MyBadParcelable()36     public MyBadParcelable() {
37     }
38 
writeToParcel(Parcel out, int flags)39     public void writeToParcel(Parcel out, int flags) {
40         out.writeString("I am bad");
41     }
42 
describeContents()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 
MyBadParcelable(Parcel in)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 {
startTiming(boolean realTime)65         public void startTiming(boolean realTime);
addIntermediate(String name)66         public void addIntermediate(String name);
addIntermediate(String name, long timeInNS)67         public void addIntermediate(String name, long timeInNS);
finishTiming(boolean realTime)68         public void finishTiming(boolean realTime);
activityFinished(int resultCode, Intent data, RuntimeException where)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 
setCallingTest(CallingTest ct)160     public static void setCallingTest(CallingTest ct) {
161         sCallingTest = ct;
162     }
163 
LaunchpadActivity()164     public LaunchpadActivity() {
165         mStartTime = System.currentTimeMillis();
166     }
167 
168     @Override
onCreate(Bundle icicle)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
onStart()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
onRestart()209     protected void onRestart() {
210         super.onStart();
211         checkLifecycle(ON_RESTART);
212     }
213 
214     @Override
onResume()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
onSaveInstanceState(Bundle icicle)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
onPause()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
onStop()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
onActivityResult(int requestCode, int resultCode, Intent data)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
onDestroy()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 
setExpectedLifecycle(String[] lifecycle)372     private void setExpectedLifecycle(String[] lifecycle) {
373         mExpectedLifecycle = lifecycle;
374         mNextLifecycle = 0;
375     }
376 
checkLifecycle(String where)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 
setExpectedReceivers(String[] receivers)428     private void setExpectedReceivers(String[] receivers) {
429         mExpectedReceivers = receivers;
430         mNextReceiver = 0;
431     }
432 
setExpectedData(String[] data)433     private void setExpectedData(String[] data) {
434         mExpectedData = data;
435         mReceivedData = new boolean[data.length];
436     }
437 
makeBroadcastIntent(String action)438     private Intent makeBroadcastIntent(String action) {
439         Intent intent = new Intent(action, null);
440         intent.putExtra("caller", mCallTarget);
441         return intent;
442     }
443 
finishGood()444     private void finishGood() {
445         finishWithResult(RESULT_OK, null);
446     }
447 
finishBad(String error)448     private void finishBad(String error) {
449         finishWithResult(RESULT_CANCELED, (new Intent()).setAction(error));
450     }
451 
finishWithResult(int resultCode, Intent data)452     private void finishWithResult(int resultCode, Intent data) {
453         setTestResult(resultCode, data);
454         finish();
455     }
456 
setTestResult(int resultCode, Intent data)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 
registerMyReceiver(IntentFilter filter)466     private void registerMyReceiver(IntentFilter filter) {
467         mReceiverRegistered = true;
468         //System.out.println("Registering: " + mReceiver);
469         registerReceiver(mReceiver, filter);
470     }
471 
unregisterMyReceiver()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 
gotReceive(String name, Intent intent)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