BroadcastTest.java revision 742a67127366c376fdf188ff99ba30b27d3bf90c
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
17package android.app.activity;
18
19import android.app.Activity;
20import android.app.ActivityManagerNative;
21import android.content.BroadcastReceiver;
22import android.content.Context;
23import android.content.Intent;
24import android.content.IntentFilter;
25import android.os.Binder;
26import android.os.Bundle;
27import android.os.IBinder;
28import android.os.Parcel;
29import android.test.FlakyTest;
30import android.test.suitebuilder.annotation.Suppress;
31import android.util.Log;
32
33import java.util.Arrays;
34
35public class BroadcastTest extends ActivityTestsBase {
36    public static final int BROADCAST_TIMEOUT = 5 * 1000;
37
38    public static final String BROADCAST_REGISTERED =
39            "com.android.frameworks.coretests.activity.BROADCAST_REGISTERED";
40    public static final String BROADCAST_LOCAL =
41            "com.android.frameworks.coretests.activity.BROADCAST_LOCAL";
42    public static final String BROADCAST_LOCAL_GRANTED =
43            "com.android.frameworks.coretests.activity.BROADCAST_LOCAL_GRANTED";
44    public static final String BROADCAST_LOCAL_DENIED =
45            "com.android.frameworks.coretests.activity.BROADCAST_LOCAL_DENIED";
46    public static final String BROADCAST_REMOTE =
47            "com.android.frameworks.coretests.activity.BROADCAST_REMOTE";
48    public static final String BROADCAST_REMOTE_GRANTED =
49            "com.android.frameworks.coretests.activity.BROADCAST_REMOTE_GRANTED";
50    public static final String BROADCAST_REMOTE_DENIED =
51            "com.android.frameworks.coretests.activity.BROADCAST_REMOTE_DENIED";
52    public static final String BROADCAST_ALL =
53            "com.android.frameworks.coretests.activity.BROADCAST_ALL";
54    public static final String BROADCAST_MULTI =
55            "com.android.frameworks.coretests.activity.BROADCAST_MULTI";
56    public static final String BROADCAST_ABORT =
57            "com.android.frameworks.coretests.activity.BROADCAST_ABORT";
58
59    public static final String BROADCAST_STICKY1 =
60            "com.android.frameworks.coretests.activity.BROADCAST_STICKY1";
61    public static final String BROADCAST_STICKY2 =
62            "com.android.frameworks.coretests.activity.BROADCAST_STICKY2";
63
64    public static final String BROADCAST_FAIL_REGISTER =
65            "com.android.frameworks.coretests.activity.BROADCAST_FAIL_REGISTER";
66    public static final String BROADCAST_FAIL_BIND =
67            "com.android.frameworks.coretests.activity.BROADCAST_FAIL_BIND";
68
69    public static final String RECEIVER_REG = "receiver-reg";
70    public static final String RECEIVER_LOCAL = "receiver-local";
71    public static final String RECEIVER_REMOTE = "receiver-remote";
72    public static final String RECEIVER_ABORT = "receiver-abort";
73    public static final String RECEIVER_RESULTS = "receiver-results";
74
75    public static final String DATA_1 = "one";
76    public static final String DATA_2 = "two";
77
78    public static final int GOT_RECEIVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
79    public static final int ERROR_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 1;
80
81    private String[] mExpectedReceivers = null;
82    private int mNextReceiver;
83
84    private String[] mExpectedData = null;
85    private boolean[] mReceivedData = null;
86
87    boolean mReceiverRegistered = false;
88
89    public void setExpectedReceivers(String[] receivers) {
90        mExpectedReceivers = receivers;
91        mNextReceiver = 0;
92    }
93
94    public void setExpectedData(String[] data) {
95        mExpectedData = data;
96        mReceivedData = new boolean[data.length];
97    }
98
99    public void onTimeout() {
100        String msg = "Timeout";
101        if (mExpectedReceivers != null && mNextReceiver < mExpectedReceivers.length) {
102            msg = msg + " waiting for " + mExpectedReceivers[mNextReceiver];
103        }
104        finishBad(msg);
105    }
106
107    public Intent makeBroadcastIntent(String action) {
108        Intent intent = new Intent(action, null);
109        intent.putExtra("caller", mCallTarget);
110        return intent;
111    }
112
113    public void finishWithResult(int resultCode, Intent data) {
114        unregisterMyReceiver();
115        super.finishWithResult(resultCode, data);
116    }
117
118    public final void gotReceive(String name, Intent intent) {
119        synchronized (this) {
120
121            //System.out.println("Got receive: " + name);
122            //System.out.println(mNextReceiver + " in " + mExpectedReceivers);
123            //new RuntimeException("stack").printStackTrace();
124
125            addIntermediate(name);
126
127            if (mExpectedData != null) {
128                int n = mExpectedData.length;
129                int i;
130                boolean prev = false;
131                for (i = 0; i < n; i++) {
132                    if (mExpectedData[i].equals(intent.getStringExtra("test"))) {
133                        if (mReceivedData[i]) {
134                            prev = true;
135                            continue;
136                        }
137                        mReceivedData[i] = true;
138                        break;
139                    }
140                }
141                if (i >= n) {
142                    if (prev) {
143                        finishBad("Receive got data too many times: "
144                                + intent.getStringExtra("test"));
145                    } else {
146                        finishBad("Receive got unexpected data: "
147                                + intent.getStringExtra("test"));
148                    }
149                    new RuntimeException("stack").printStackTrace();
150                    return;
151                }
152            }
153
154            if (mNextReceiver >= mExpectedReceivers.length) {
155                finishBad("Got too many onReceiveIntent() calls!");
156//                System.out.println("Too many intents received: now at "
157//                        + mNextReceiver + ", expect list: "
158//                        + Arrays.toString(mExpectedReceivers));
159                fail("Got too many onReceiveIntent() calls!");
160            } else if (!mExpectedReceivers[mNextReceiver].equals(name)) {
161                finishBad("Receive out of order: got " + name
162                        + " but expected "
163                        + mExpectedReceivers[mNextReceiver]);
164                fail("Receive out of order: got " + name
165                        + " but expected "
166                        + mExpectedReceivers[mNextReceiver]);
167            } else {
168                mNextReceiver++;
169                if (mNextReceiver == mExpectedReceivers.length) {
170                    finishTest();
171                }
172            }
173        }
174    }
175
176    public void registerMyReceiver(IntentFilter filter, String permission) {
177        mReceiverRegistered = true;
178        //System.out.println("Registering: " + mReceiver);
179        getContext().registerReceiver(mReceiver, filter, permission, null);
180    }
181
182    public void unregisterMyReceiver() {
183        if (mReceiverRegistered) {
184            unregisterMyReceiverNoCheck();
185        }
186    }
187
188    public void unregisterMyReceiverNoCheck() {
189        mReceiverRegistered = false;
190        //System.out.println("Unregistering: " + mReceiver);
191        getContext().unregisterReceiver(mReceiver);
192    }
193
194    public void onRegisteredReceiver(Intent intent) {
195        gotReceive(RECEIVER_REG, intent);
196    }
197
198    private Binder mCallTarget = new Binder() {
199        public boolean onTransact(int code, Parcel data, Parcel reply,
200                int flags) {
201            data.setDataPosition(0);
202            data.enforceInterface(LaunchpadActivity.LAUNCH);
203            if (code == GOT_RECEIVE_TRANSACTION) {
204                String name = data.readString();
205                gotReceive(name, null);
206                return true;
207            } else if (code == ERROR_TRANSACTION) {
208                finishBad(data.readString());
209                return true;
210            }
211            return false;
212        }
213    };
214
215    private void finishTest() {
216        if (mReceiverRegistered) {
217            addIntermediate("before-unregister");
218            unregisterMyReceiver();
219        }
220        finishTiming(true);
221        finishGood();
222    }
223
224    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
225        public void onReceive(Context context, Intent intent) {
226            //System.out.println("Receive in: " + this + ": " + intent);
227            onRegisteredReceiver(intent);
228        }
229    };
230
231    // Mark flaky until http://b/issue?id=1191607 is resolved.
232    @FlakyTest(tolerance=2)
233    public void testRegistered() throws Exception {
234        runLaunchpad(LaunchpadActivity.BROADCAST_REGISTERED);
235    }
236
237    public void testLocal() throws Exception {
238        runLaunchpad(LaunchpadActivity.BROADCAST_LOCAL);
239    }
240
241    public void testRemote() throws Exception {
242        runLaunchpad(LaunchpadActivity.BROADCAST_REMOTE);
243    }
244
245    public void testAbort() throws Exception {
246        runLaunchpad(LaunchpadActivity.BROADCAST_ABORT);
247    }
248
249    @FlakyTest(tolerance=2)
250    public void testAll() throws Exception {
251        runLaunchpad(LaunchpadActivity.BROADCAST_ALL);
252    }
253
254    @FlakyTest(tolerance=2)
255    public void testMulti() throws Exception {
256        runLaunchpad(LaunchpadActivity.BROADCAST_MULTI);
257    }
258
259    private class TestBroadcastReceiver extends BroadcastReceiver {
260        public boolean mHaveResult = false;
261
262        @Override
263        public void onReceive(Context context, Intent intent) {
264            synchronized (BroadcastTest.this) {
265                mHaveResult = true;
266                BroadcastTest.this.notifyAll();
267            }
268        }
269    }
270
271    public void testResult() throws Exception {
272        TestBroadcastReceiver broadcastReceiver = new TestBroadcastReceiver();
273
274        synchronized (this) {
275            Bundle map = new Bundle();
276            map.putString("foo", "you");
277            map.putString("remove", "me");
278            getContext().sendOrderedBroadcast(
279                    new Intent("com.android.frameworks.coretests.activity.BROADCAST_RESULT"),
280                    null, broadcastReceiver, null, 1, "foo", map);
281            while (!broadcastReceiver.mHaveResult) {
282                try {
283                    wait();
284                } catch (InterruptedException e) {
285                }
286            }
287
288            //System.out.println("Code: " + mResultCode + ", data: " + mResultData);
289            //System.out.println("Extras: " + mResultExtras);
290
291            assertEquals("Incorrect code: " + broadcastReceiver.getResultCode(),
292                    3, broadcastReceiver.getResultCode());
293
294            assertEquals("bar", broadcastReceiver.getResultData());
295
296            Bundle resultExtras = broadcastReceiver.getResultExtras(false);
297            assertEquals("them", resultExtras.getString("bar"));
298            assertEquals("you", resultExtras.getString("foo"));
299            assertNull(resultExtras.getString("remove"));
300        }
301    }
302
303    public void testSetSticky() throws Exception {
304        Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
305        intent.putExtra("test", LaunchpadActivity.DATA_1);
306        ActivityManagerNative.getDefault().unbroadcastIntent(null, intent,
307                Binder.getOrigCallingUser());
308
309        ActivityManagerNative.broadcastStickyIntent(intent, null);
310        addIntermediate("finished-broadcast");
311
312        IntentFilter filter = new IntentFilter(LaunchpadActivity.BROADCAST_STICKY1);
313        Intent sticky = getContext().registerReceiver(null, filter);
314        assertNotNull("Sticky not found", sticky);
315        assertEquals(LaunchpadActivity.DATA_1, sticky.getStringExtra("test"));
316    }
317
318    public void testClearSticky() throws Exception {
319        Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
320        intent.putExtra("test", LaunchpadActivity.DATA_1);
321        ActivityManagerNative.broadcastStickyIntent(intent, null);
322
323        ActivityManagerNative.getDefault().unbroadcastIntent(
324                null, new Intent(LaunchpadActivity.BROADCAST_STICKY1, null),
325                Binder.getOrigCallingUser());
326        addIntermediate("finished-unbroadcast");
327
328        IntentFilter filter = new IntentFilter(LaunchpadActivity.BROADCAST_STICKY1);
329        Intent sticky = getContext().registerReceiver(null, filter);
330        assertNull("Sticky not found", sticky);
331    }
332
333    public void testReplaceSticky() throws Exception {
334        Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
335        intent.putExtra("test", LaunchpadActivity.DATA_1);
336        ActivityManagerNative.broadcastStickyIntent(intent, null);
337        intent.putExtra("test", LaunchpadActivity.DATA_2);
338
339        ActivityManagerNative.broadcastStickyIntent(intent, null);
340        addIntermediate("finished-broadcast");
341
342        IntentFilter filter = new IntentFilter(LaunchpadActivity.BROADCAST_STICKY1);
343        Intent sticky = getContext().registerReceiver(null, filter);
344        assertNotNull("Sticky not found", sticky);
345        assertEquals(LaunchpadActivity.DATA_2, sticky.getStringExtra("test"));
346    }
347
348    // Marking flaky until http://b/issue?id=1191337 is resolved
349    @FlakyTest(tolerance=2)
350    public void testReceiveSticky() throws Exception {
351        Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
352        intent.putExtra("test", LaunchpadActivity.DATA_1);
353        ActivityManagerNative.broadcastStickyIntent(intent, null);
354
355        runLaunchpad(LaunchpadActivity.BROADCAST_STICKY1);
356    }
357
358    // Marking flaky until http://b/issue?id=1191337 is resolved
359    @FlakyTest(tolerance=2)
360    public void testReceive2Sticky() throws Exception {
361        Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
362        intent.putExtra("test", LaunchpadActivity.DATA_1);
363        ActivityManagerNative.broadcastStickyIntent(intent, null);
364        intent = new Intent(LaunchpadActivity.BROADCAST_STICKY2, null);
365        intent.putExtra("test", LaunchpadActivity.DATA_2);
366        ActivityManagerNative.broadcastStickyIntent(intent, null);
367
368        runLaunchpad(LaunchpadActivity.BROADCAST_STICKY2);
369    }
370
371    public void testRegisteredReceivePermissionGranted() throws Exception {
372        setExpectedReceivers(new String[]{RECEIVER_REG});
373        registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED), PERMISSION_GRANTED);
374        addIntermediate("after-register");
375        getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_REGISTERED));
376        waitForResultOrThrow(BROADCAST_TIMEOUT);
377    }
378
379    public void testRegisteredReceivePermissionDenied() throws Exception {
380        setExpectedReceivers(new String[]{RECEIVER_RESULTS});
381        registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED), PERMISSION_DENIED);
382        addIntermediate("after-register");
383
384        BroadcastReceiver finish = new BroadcastReceiver() {
385            public void onReceive(Context context, Intent intent) {
386                gotReceive(RECEIVER_RESULTS, intent);
387            }
388        };
389
390        getContext().sendOrderedBroadcast(
391                makeBroadcastIntent(BROADCAST_REGISTERED),
392                null, finish, null, Activity.RESULT_CANCELED, null, null);
393        waitForResultOrThrow(BROADCAST_TIMEOUT);
394    }
395
396    public void testRegisteredBroadcastPermissionGranted() throws Exception {
397        setExpectedReceivers(new String[]{RECEIVER_REG});
398        registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED), null);
399        addIntermediate("after-register");
400        getContext().sendBroadcast(
401                makeBroadcastIntent(BROADCAST_REGISTERED),
402                PERMISSION_GRANTED);
403        waitForResultOrThrow(BROADCAST_TIMEOUT);
404    }
405
406    public void testRegisteredBroadcastPermissionDenied() throws Exception {
407        setExpectedReceivers(new String[]{RECEIVER_RESULTS});
408        registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED), null);
409        addIntermediate("after-register");
410
411        BroadcastReceiver finish = new BroadcastReceiver() {
412            public void onReceive(Context context, Intent intent) {
413                gotReceive(RECEIVER_RESULTS, intent);
414            }
415        };
416
417        getContext().sendOrderedBroadcast(
418                makeBroadcastIntent(BROADCAST_REGISTERED),
419                PERMISSION_DENIED, finish, null, Activity.RESULT_CANCELED,
420                null, null);
421        waitForResultOrThrow(BROADCAST_TIMEOUT);
422    }
423
424    public void testLocalReceivePermissionGranted() throws Exception {
425        setExpectedReceivers(new String[]{RECEIVER_LOCAL});
426        getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_LOCAL_GRANTED));
427        waitForResultOrThrow(BROADCAST_TIMEOUT);
428    }
429
430    public void testLocalReceivePermissionDenied() throws Exception {
431        setExpectedReceivers(new String[]{RECEIVER_RESULTS});
432
433        BroadcastReceiver finish = new BroadcastReceiver() {
434            public void onReceive(Context context, Intent intent) {
435                gotReceive(RECEIVER_RESULTS, intent);
436            }
437        };
438
439        getContext().sendOrderedBroadcast(
440                makeBroadcastIntent(BROADCAST_LOCAL_DENIED),
441                null, finish, null, Activity.RESULT_CANCELED,
442                null, null);
443        waitForResultOrThrow(BROADCAST_TIMEOUT);
444    }
445
446    public void testLocalBroadcastPermissionGranted() throws Exception {
447        setExpectedReceivers(new String[]{RECEIVER_LOCAL});
448        getContext().sendBroadcast(
449                makeBroadcastIntent(BROADCAST_LOCAL),
450                PERMISSION_GRANTED);
451        waitForResultOrThrow(BROADCAST_TIMEOUT);
452    }
453
454    public void testLocalBroadcastPermissionDenied() throws Exception {
455        setExpectedReceivers(new String[]{RECEIVER_RESULTS});
456
457        BroadcastReceiver finish = new BroadcastReceiver() {
458            public void onReceive(Context context, Intent intent) {
459                gotReceive(RECEIVER_RESULTS, intent);
460            }
461        };
462
463        getContext().sendOrderedBroadcast(
464                makeBroadcastIntent(BROADCAST_LOCAL),
465                PERMISSION_DENIED, finish, null, Activity.RESULT_CANCELED,
466                null, null);
467        waitForResultOrThrow(BROADCAST_TIMEOUT);
468    }
469
470    public void testRemoteReceivePermissionGranted() throws Exception {
471        setExpectedReceivers(new String[]{RECEIVER_REMOTE});
472        getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_REMOTE_GRANTED));
473        waitForResultOrThrow(BROADCAST_TIMEOUT);
474    }
475
476    public void testRemoteReceivePermissionDenied() throws Exception {
477        setExpectedReceivers(new String[]{RECEIVER_RESULTS});
478
479        BroadcastReceiver finish = new BroadcastReceiver() {
480            public void onReceive(Context context, Intent intent) {
481                gotReceive(RECEIVER_RESULTS, intent);
482            }
483        };
484
485        getContext().sendOrderedBroadcast(
486                makeBroadcastIntent(BROADCAST_REMOTE_DENIED),
487                null, finish, null, Activity.RESULT_CANCELED,
488                null, null);
489        waitForResultOrThrow(BROADCAST_TIMEOUT);
490    }
491
492    public void testRemoteBroadcastPermissionGranted() throws Exception {
493        setExpectedReceivers(new String[]{RECEIVER_REMOTE});
494        getContext().sendBroadcast(
495                makeBroadcastIntent(BROADCAST_REMOTE),
496                PERMISSION_GRANTED);
497        waitForResultOrThrow(BROADCAST_TIMEOUT);
498    }
499
500    public void testRemoteBroadcastPermissionDenied() throws Exception {
501        setExpectedReceivers(new String[]{RECEIVER_RESULTS});
502
503        BroadcastReceiver finish = new BroadcastReceiver() {
504            public void onReceive(Context context, Intent intent) {
505                gotReceive(RECEIVER_RESULTS, intent);
506            }
507        };
508
509        getContext().sendOrderedBroadcast(
510                makeBroadcastIntent(BROADCAST_REMOTE),
511                PERMISSION_DENIED, finish, null, Activity.RESULT_CANCELED,
512                null, null);
513        waitForResultOrThrow(BROADCAST_TIMEOUT);
514    }
515
516    public void testReceiverCanNotRegister() throws Exception {
517        setExpectedReceivers(new String[]{RECEIVER_LOCAL});
518        getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_FAIL_REGISTER));
519        waitForResultOrThrow(BROADCAST_TIMEOUT);
520    }
521
522    public void testReceiverCanNotBind() throws Exception {
523        setExpectedReceivers(new String[]{RECEIVER_LOCAL});
524        getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_FAIL_BIND));
525        waitForResultOrThrow(BROADCAST_TIMEOUT);
526    }
527
528    public void testLocalUnregisterTwice() throws Exception {
529        registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED), null);
530        unregisterMyReceiverNoCheck();
531        try {
532            unregisterMyReceiverNoCheck();
533            fail("No exception thrown on second unregister");
534        } catch (IllegalArgumentException e) {
535            Log.i("foo", "Unregister exception", e);
536        }
537    }
538}
539