• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.cts;
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         public void startTiming(boolean realTime);
71 
addIntermediate(String name)72         public void addIntermediate(String name);
73 
addIntermediate(String name, long timeInNS)74         public void addIntermediate(String name, long timeInNS);
75 
finishTiming(boolean realTime)76         public void finishTiming(boolean realTime);
77 
activityFinished(int resultCode, Intent data, RuntimeException where)78         public void activityFinished(int resultCode, Intent data, RuntimeException where);
79     }
80 
81     // Also used as the Binder interface descriptor string in these tests
82     public static final String LAUNCH = "android.app.cts.activity.LAUNCH";
83 
84     public static final String FORWARD_RESULT = "android.app.cts.activity.FORWARD_RESULT";
85     public static final String RETURNED_RESULT = "android.app.cts.activity.RETURNED_RESULT";
86 
87     public static final String BAD_PARCELABLE = "android.app.cts.activity.BAD_PARCELABLE";
88 
89     public static final int LAUNCHED_RESULT = 1;
90     public static final int FORWARDED_RESULT = 2;
91 
92     public static final String LIFECYCLE_BASIC = "android.app.cts.activity.LIFECYCLE_BASIC";
93     public static final String LIFECYCLE_SCREEN = "android.app.cts.activity.LIFECYCLE_SCREEN";
94     public static final String LIFECYCLE_DIALOG = "android.app.cts.activity.LIFECYCLE_DIALOG";
95 
96     public static final String BROADCAST_REGISTERED = "android.app.cts.activity.BROADCAST_REGISTERED";
97     public static final String BROADCAST_LOCAL = "android.app.cts.activity.BROADCAST_LOCAL";
98     public static final String BROADCAST_REMOTE = "android.app.cts.activity.BROADCAST_REMOTE";
99     public static final String BROADCAST_ALL = "android.app.cts.activity.BROADCAST_ALL";
100     public static final String BROADCAST_REPEAT = "android.app.cts.activity.BROADCAST_REPEAT";
101     public static final String BROADCAST_MULTI = "android.app.cts.activity.BROADCAST_MULTI";
102     public static final String BROADCAST_ABORT = "android.app.cts.activity.BROADCAST_ABORT";
103 
104     public static final String EXPANDLIST_SELECT = "EXPANDLIST_SELECT";
105     public static final String EXPANDLIST_VIEW = "EXPANDLIST_VIEW";
106     public static final String EXPANDLIST_CALLBACK = "EXPANDLIST_CALLBACK";
107 
108     public static final String BROADCAST_STICKY1 = "android.app.cts.activity.BROADCAST_STICKY1";
109     public static final String BROADCAST_STICKY2 = "android.app.cts.activity.BROADCAST_STICKY2";
110 
111     public static final String ALIAS_ACTIVITY = "android.app.cts.activity.ALIAS_ACTIVITY";
112 
113     public static final String RECEIVER_REG = "receiver-reg";
114     public static final String RECEIVER_LOCAL = "receiver-local";
115     public static final String RECEIVER_REMOTE = "receiver-remote";
116     public static final String RECEIVER_ABORT = "receiver-abort";
117 
118     public static final String DATA_1 = "one";
119     public static final String DATA_2 = "two";
120 
121     public static final String ON_START = "onStart";
122     public static final String ON_RESTART = "onRestart";
123     public static final String ON_RESUME = "onResume";
124     public static final String ON_FREEZE = "onSaveInstanceState";
125     public static final String ON_PAUSE = "onPause";
126 
127     // ON_STOP and ON_DESTROY are not tested because they may not be called.
128 
129     public static final String DO_FINISH = "finish";
130     public static final String DO_LOCAL_SCREEN = "local-screen";
131     public static final String DO_LOCAL_DIALOG = "local-dialog";
132 
133     private static final String TAG = "LaunchpadActivity";
134 
135     private boolean mBadParcelable = false;
136 
137     private boolean mStarted = false;
138 
139     private int mResultCode = RESULT_CANCELED;
140     private Intent mData = new Intent().setAction("No result received");
141     private RuntimeException mResultStack = null;
142 
143     /** Index into the {@link #mNextLifecycle} array. */
144     private int mNextLifecycle;
145 
146     /** Current lifecycle expected to be followed. */
147     private String[] mExpectedLifecycle;
148 
149     /** Other possible lifecycles. Never includes the current {@link #mExpectedLifecycle}. */
150     private List<String[]> mOtherPossibleLifecycles = new ArrayList<String[]>(2);
151 
152     /** Map from lifecycle arrays to debugging log names. */
153     private Map<String[], String> mLifecycleNames = new HashMap<String[], String>(2);
154 
155     private String[] mExpectedReceivers = null;
156     private int mNextReceiver;
157 
158     private String[] mExpectedData = null;
159     private boolean[] mReceivedData = null;
160 
161     boolean mReceiverRegistered = false;
162 
163     private static CallingTest sCallingTest = null;
164 
setCallingTest(CallingTest ct)165     public static void setCallingTest(CallingTest ct) {
166         sCallingTest = ct;
167     }
168 
LaunchpadActivity()169     public LaunchpadActivity() {
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 
287             } else if (FORWARD_RESULT.equals(action)) {
288                 final Intent intent = getIntent();
289                 intent.setFlags(0);
290                 intent.setClass(this, LocalScreen.class);
291                 startActivityForResult(intent, FORWARDED_RESULT);
292             } else if (BAD_PARCELABLE.equals(action)) {
293                 mBadParcelable = true;
294                 final Intent intent = getIntent();
295                 intent.setFlags(0);
296                 intent.setClass(this, LocalScreen.class);
297                 startActivityForResult(intent, LAUNCHED_RESULT);
298             } else if (BROADCAST_REGISTERED.equals(action)) {
299                 setExpectedReceivers(new String[] {
300                     RECEIVER_REG
301                 });
302                 registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED));
303                 sCallingTest.addIntermediate("after-register");
304                 sendBroadcast(makeBroadcastIntent(BROADCAST_REGISTERED));
305             } else if (BROADCAST_LOCAL.equals(action)) {
306                 setExpectedReceivers(new String[] {
307                     RECEIVER_LOCAL
308                 });
309                 sendBroadcast(makeBroadcastIntent(BROADCAST_LOCAL));
310             } else if (BROADCAST_REMOTE.equals(action)) {
311                 setExpectedReceivers(new String[] {
312                     RECEIVER_REMOTE
313                 });
314                 sendBroadcast(makeBroadcastIntent(BROADCAST_REMOTE));
315             } else if (BROADCAST_ALL.equals(action)) {
316                 setExpectedReceivers(new String[] {
317                         RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL
318                 });
319                 registerMyReceiver(new IntentFilter(BROADCAST_ALL));
320                 sCallingTest.addIntermediate("after-register");
321                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
322             } else if (BROADCAST_MULTI.equals(action)) {
323                 setExpectedReceivers(new String[] {
324                         RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL, RECEIVER_REMOTE,
325                         RECEIVER_REG, RECEIVER_LOCAL, RECEIVER_REMOTE, RECEIVER_REG,
326                         RECEIVER_LOCAL, RECEIVER_LOCAL, RECEIVER_REMOTE, RECEIVER_LOCAL,
327                         RECEIVER_REMOTE, RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL,
328                         RECEIVER_REMOTE, RECEIVER_REG, RECEIVER_LOCAL, RECEIVER_REMOTE,
329                         RECEIVER_REG, RECEIVER_LOCAL, RECEIVER_REMOTE, RECEIVER_LOCAL,
330                         RECEIVER_REMOTE, RECEIVER_LOCAL
331                 });
332                 registerMyReceiver(new IntentFilter(BROADCAST_ALL));
333                 sCallingTest.addIntermediate("after-register");
334                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
335                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
336                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
337                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_LOCAL), null);
338                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REMOTE), null);
339                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_LOCAL), null);
340                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REMOTE), null);
341                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
342                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
343                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ALL), null);
344                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_REPEAT), null);
345             } else if (BROADCAST_ABORT.equals(action)) {
346                 setExpectedReceivers(new String[] {
347                         RECEIVER_REMOTE, RECEIVER_ABORT
348                 });
349                 registerMyReceiver(new IntentFilter(BROADCAST_ABORT));
350                 sCallingTest.addIntermediate("after-register");
351                 sendOrderedBroadcast(makeBroadcastIntent(BROADCAST_ABORT), null);
352             } else if (BROADCAST_STICKY1.equals(action)) {
353                 setExpectedReceivers(new String[] {
354                     RECEIVER_REG
355                 });
356                 setExpectedData(new String[] {
357                     DATA_1
358                 });
359                 registerMyReceiver(new IntentFilter(BROADCAST_STICKY1));
360                 sCallingTest.addIntermediate("after-register");
361             } else if (BROADCAST_STICKY2.equals(action)) {
362                 setExpectedReceivers(new String[] {
363                         RECEIVER_REG, RECEIVER_REG
364                 });
365                 setExpectedData(new String[] {
366                         DATA_1, DATA_2
367                 });
368                 final IntentFilter filter = new IntentFilter(BROADCAST_STICKY1);
369                 filter.addAction(BROADCAST_STICKY2);
370                 registerMyReceiver(filter);
371                 sCallingTest.addIntermediate("after-register");
372             } else if (ALIAS_ACTIVITY.equals(action)) {
373                 final Intent intent = getIntent();
374                 intent.setFlags(0);
375                 intent.setClass(this, AliasActivityStub.class);
376                 startActivityForResult(intent, LAUNCHED_RESULT);
377             } else if (EXPANDLIST_SELECT.equals(action)) {
378                 final Intent intent = getIntent();
379                 intent.setFlags(0);
380                 intent.setAction(action);
381                 intent.setComponent((ComponentName) intent.getParcelableExtra("component"));
382                 startActivityForResult(intent, LAUNCHED_RESULT);
383             } else if (EXPANDLIST_VIEW.equals(action)) {
384                 final Intent intent = getIntent();
385                 intent.setFlags(0);
386                 intent.setAction(action);
387                 intent.setComponent((ComponentName) intent.getParcelableExtra("component"));
388                 startActivityForResult(intent, LAUNCHED_RESULT);
389             } else if (EXPANDLIST_CALLBACK.equals(action)) {
390                 final Intent intent = getIntent();
391                 intent.setFlags(0);
392                 intent.setAction(action);
393                 intent.setComponent((ComponentName) intent.getParcelableExtra("component"));
394                 startActivityForResult(intent, LAUNCHED_RESULT);
395             }
396         }
397     }
398 
399     @Override
onSaveInstanceState(Bundle icicle)400     protected void onSaveInstanceState(Bundle icicle) {
401         super.onSaveInstanceState(icicle);
402         if (mBadParcelable) {
403             icicle.putParcelable("baddy", new MyBadParcelable());
404         }
405     }
406 
407     @Override
onPause()408     protected void onPause() {
409         super.onPause();
410         checkLifecycle(ON_PAUSE);
411     }
412 
413     @Override
onActivityResult(int requestCode, int resultCode, Intent data)414     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
415         switch (requestCode) {
416             case LAUNCHED_RESULT:
417                 sCallingTest.finishTiming(true);
418                 finishWithResult(resultCode, data);
419                 break;
420             case FORWARDED_RESULT:
421                 sCallingTest.finishTiming(true);
422                 if (RETURNED_RESULT.equals(data.getAction())) {
423                     finishWithResult(resultCode, data);
424                 } else {
425                     finishWithResult(RESULT_CANCELED, new Intent().setAction("Bad data returned: "
426                             + data));
427                 }
428                 break;
429             default:
430                 sCallingTest.finishTiming(true);
431                 finishWithResult(RESULT_CANCELED, new Intent()
432                         .setAction("Unexpected request code: " + requestCode));
433                 break;
434         }
435     }
436 
checkLifecycle(String where)437     private void checkLifecycle(String where) {
438         String action = getIntent().getAction();
439 
440         if (mExpectedLifecycle == null) {
441             return;
442         }
443 
444         if (mNextLifecycle >= mExpectedLifecycle.length) {
445             finishBad("Activity lifecycle for " + action + " incorrect: received " + where
446                     + " but don't expect any more calls");
447             mExpectedLifecycle = null;
448             return;
449         }
450 
451         do {
452             if (mExpectedLifecycle[mNextLifecycle].equals(where)) {
453                 Log.w(TAG, "Matched: " + where);
454                 break;
455             } else {
456                 Log.w(TAG, "Expected " + mExpectedLifecycle[mNextLifecycle] + " but got " + where);
457             }
458         } while (switchToNextPossibleLifecycle());
459 
460         if (mExpectedLifecycle == null) {
461             finishBad("Activity lifecycle for " + action + " incorrect: received " + where
462                     + " at " + mNextLifecycle);
463             return;
464         }
465 
466         mNextLifecycle++;
467 
468         if (mNextLifecycle >= mExpectedLifecycle.length) {
469             finishGood();
470             return;
471         }
472 
473         final String next = mExpectedLifecycle[mNextLifecycle];
474         if (next.equals(DO_FINISH)) {
475             mNextLifecycle++;
476             if (mNextLifecycle >= mExpectedLifecycle.length) {
477                 setTestResult(RESULT_OK, null);
478             }
479             if (!isFinishing()) {
480                 finish();
481             }
482         } else if (next.equals(DO_LOCAL_SCREEN)) {
483             mNextLifecycle++;
484             final Intent intent = new Intent(TestedScreen.WAIT_BEFORE_FINISH);
485             intent.setClass(this, LocalScreen.class);
486             startActivity(intent);
487         } else if (next.equals(DO_LOCAL_DIALOG)) {
488             mNextLifecycle++;
489             final Intent intent = new Intent(TestedScreen.WAIT_BEFORE_FINISH);
490             intent.setClass(this, LocalDialog.class);
491             startActivity(intent);
492         }
493     }
494 
setExpectedReceivers(String[] receivers)495     private void setExpectedReceivers(String[] receivers) {
496         mExpectedReceivers = receivers;
497         mNextReceiver = 0;
498     }
499 
setExpectedData(String[] data)500     private void setExpectedData(String[] data) {
501         mExpectedData = data;
502         mReceivedData = new boolean[data.length];
503     }
504 
505     @SuppressWarnings("deprecation")
makeBroadcastIntent(String action)506     private Intent makeBroadcastIntent(String action) {
507         final Intent intent = new Intent(action, null);
508         intent.putExtra("caller", mCallTarget);
509         return intent;
510     }
511 
finishGood()512     private void finishGood() {
513         finishWithResult(RESULT_OK, null);
514     }
515 
finishBad(String error)516     private void finishBad(String error) {
517         finishWithResult(RESULT_CANCELED, new Intent().setAction(error));
518     }
519 
finishWithResult(int resultCode, Intent data)520     private void finishWithResult(int resultCode, Intent data) {
521         setTestResult(resultCode, data);
522         finish();
523 
524         // Member fields set by calling setTestResult above...
525         sCallingTest.activityFinished(mResultCode, mData, mResultStack);
526     }
527 
setTestResult(int resultCode, Intent data)528     private void setTestResult(int resultCode, Intent data) {
529         mHandler.removeCallbacks(mTimeout);
530         unregisterMyReceiver();
531         mResultCode = resultCode;
532         mData = data;
533         mResultStack = new RuntimeException("Original error was here");
534         mResultStack.fillInStackTrace();
535     }
536 
registerMyReceiver(IntentFilter filter)537     private void registerMyReceiver(IntentFilter filter) {
538         mReceiverRegistered = true;
539         registerReceiver(mReceiver, filter);
540     }
541 
unregisterMyReceiver()542     private void unregisterMyReceiver() {
543         if (mReceiverRegistered) {
544             mReceiverRegistered = false;
545             unregisterReceiver(mReceiver);
546         }
547     }
548 
549     private final Handler mHandler = new Handler() {
550         @Override
551         public void handleMessage(Message msg) {
552         }
553     };
554 
555     static final int GOT_RECEIVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
556     static final int ERROR_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 1;
557 
558     private final Binder mCallTarget = new Binder() {
559         @Override
560         public boolean onTransact(int code, Parcel data, Parcel reply, int flags) {
561             data.setDataPosition(0);
562             data.enforceInterface(LaunchpadActivity.LAUNCH);
563             if (code == GOT_RECEIVE_TRANSACTION) {
564                 final String name = data.readString();
565                 gotReceive(name, null);
566                 return true;
567             } else if (code == ERROR_TRANSACTION) {
568                 finishBad(data.readString());
569                 return true;
570             }
571             return false;
572         }
573     };
574 
gotReceive(String name, Intent intent)575     private final void gotReceive(String name, Intent intent) {
576         synchronized (this) {
577 
578             sCallingTest.addIntermediate(mNextReceiver + "-" + name);
579 
580             if (mExpectedData != null) {
581                 final int n = mExpectedData.length;
582                 int i;
583                 boolean prev = false;
584                 for (i = 0; i < n; i++) {
585                     if (mExpectedData[i].equals(intent.getStringExtra("test"))) {
586                         if (mReceivedData[i]) {
587                             prev = true;
588                             continue;
589                         }
590                         mReceivedData[i] = true;
591                         break;
592                     }
593                 }
594                 if (i >= n) {
595                     if (prev) {
596                         finishBad("Receive got data too many times: "
597                                 + intent.getStringExtra("test"));
598                     } else {
599                         finishBad("Receive got unexpected data: " + intent.getStringExtra("test"));
600                     }
601                     return;
602                 }
603             }
604 
605             if (mNextReceiver >= mExpectedReceivers.length) {
606                 finishBad("Got too many onReceiveIntent() calls!");
607             } else if (!mExpectedReceivers[mNextReceiver].equals(name)) {
608                 finishBad("Receive out of order: got " + name + " but expected "
609                         + mExpectedReceivers[mNextReceiver] + " at " + mNextReceiver);
610             } else {
611                 mNextReceiver++;
612                 if (mNextReceiver == mExpectedReceivers.length) {
613                     mHandler.post(mUnregister);
614                 }
615             }
616 
617         }
618     }
619 
620     private final Runnable mUnregister = new Runnable() {
621         public void run() {
622             if (mReceiverRegistered) {
623                 sCallingTest.addIntermediate("before-unregister");
624                 unregisterMyReceiver();
625             }
626             sCallingTest.finishTiming(true);
627             finishGood();
628         }
629     };
630 
631     private final Runnable mTimeout = new Runnable() {
632         public void run() {
633             Log.i(TAG, "timeout");
634             String msg = "Timeout";
635             if (mExpectedReceivers != null && mNextReceiver < mExpectedReceivers.length) {
636                 msg = msg + " waiting for " + mExpectedReceivers[mNextReceiver];
637             }
638             finishBad(msg);
639         }
640     };
641 
642     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
643         @Override
644         public void onReceive(Context context, Intent intent) {
645             gotReceive(RECEIVER_REG, intent);
646         }
647     };
648 }
649