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.app.ActivityManagerNative;
     21 import android.content.BroadcastReceiver;
     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.IBinder;
     28 import android.os.Parcel;
     29 import android.test.FlakyTest;
     30 import android.test.suitebuilder.annotation.Suppress;
     31 import android.util.Log;
     32 
     33 import java.util.Arrays;
     34 
     35 public 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 
    308         ActivityManagerNative.broadcastStickyIntent(intent, null);
    309         addIntermediate("finished-broadcast");
    310 
    311         IntentFilter filter = new IntentFilter(LaunchpadActivity.BROADCAST_STICKY1);
    312         Intent sticky = getContext().registerReceiver(null, filter);
    313         assertNotNull("Sticky not found", sticky);
    314         assertEquals(LaunchpadActivity.DATA_1, sticky.getStringExtra("test"));
    315     }
    316 
    317     public void testClearSticky() throws Exception {
    318         Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
    319         intent.putExtra("test", LaunchpadActivity.DATA_1);
    320         ActivityManagerNative.broadcastStickyIntent(intent, null);
    321 
    322         ActivityManagerNative.getDefault().unbroadcastIntent(
    323                 null, new Intent(LaunchpadActivity.BROADCAST_STICKY1, null));
    324         addIntermediate("finished-unbroadcast");
    325 
    326         IntentFilter filter = new IntentFilter(LaunchpadActivity.BROADCAST_STICKY1);
    327         Intent sticky = getContext().registerReceiver(null, filter);
    328         assertNull("Sticky not found", sticky);
    329     }
    330 
    331     public void testReplaceSticky() throws Exception {
    332         Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
    333         intent.putExtra("test", LaunchpadActivity.DATA_1);
    334         ActivityManagerNative.broadcastStickyIntent(intent, null);
    335         intent.putExtra("test", LaunchpadActivity.DATA_2);
    336 
    337         ActivityManagerNative.broadcastStickyIntent(intent, null);
    338         addIntermediate("finished-broadcast");
    339 
    340         IntentFilter filter = new IntentFilter(LaunchpadActivity.BROADCAST_STICKY1);
    341         Intent sticky = getContext().registerReceiver(null, filter);
    342         assertNotNull("Sticky not found", sticky);
    343         assertEquals(LaunchpadActivity.DATA_2, sticky.getStringExtra("test"));
    344     }
    345 
    346     // Marking flaky until http://b/issue?id=1191337 is resolved
    347     @FlakyTest(tolerance=2)
    348     public void testReceiveSticky() throws Exception {
    349         Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
    350         intent.putExtra("test", LaunchpadActivity.DATA_1);
    351         ActivityManagerNative.broadcastStickyIntent(intent, null);
    352 
    353         runLaunchpad(LaunchpadActivity.BROADCAST_STICKY1);
    354     }
    355 
    356     // Marking flaky until http://b/issue?id=1191337 is resolved
    357     @FlakyTest(tolerance=2)
    358     public void testReceive2Sticky() throws Exception {
    359         Intent intent = new Intent(LaunchpadActivity.BROADCAST_STICKY1, null);
    360         intent.putExtra("test", LaunchpadActivity.DATA_1);
    361         ActivityManagerNative.broadcastStickyIntent(intent, null);
    362         intent = new Intent(LaunchpadActivity.BROADCAST_STICKY2, null);
    363         intent.putExtra("test", LaunchpadActivity.DATA_2);
    364         ActivityManagerNative.broadcastStickyIntent(intent, null);
    365 
    366         runLaunchpad(LaunchpadActivity.BROADCAST_STICKY2);
    367     }
    368 
    369     public void testRegisteredReceivePermissionGranted() throws Exception {
    370         setExpectedReceivers(new String[]{RECEIVER_REG});
    371         registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED), PERMISSION_GRANTED);
    372         addIntermediate("after-register");
    373         getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_REGISTERED));
    374         waitForResultOrThrow(BROADCAST_TIMEOUT);
    375     }
    376 
    377     public void testRegisteredReceivePermissionDenied() throws Exception {
    378         setExpectedReceivers(new String[]{RECEIVER_RESULTS});
    379         registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED), PERMISSION_DENIED);
    380         addIntermediate("after-register");
    381 
    382         BroadcastReceiver finish = new BroadcastReceiver() {
    383             public void onReceive(Context context, Intent intent) {
    384                 gotReceive(RECEIVER_RESULTS, intent);
    385             }
    386         };
    387 
    388         getContext().sendOrderedBroadcast(
    389                 makeBroadcastIntent(BROADCAST_REGISTERED),
    390                 null, finish, null, Activity.RESULT_CANCELED, null, null);
    391         waitForResultOrThrow(BROADCAST_TIMEOUT);
    392     }
    393 
    394     public void testRegisteredBroadcastPermissionGranted() throws Exception {
    395         setExpectedReceivers(new String[]{RECEIVER_REG});
    396         registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED), null);
    397         addIntermediate("after-register");
    398         getContext().sendBroadcast(
    399                 makeBroadcastIntent(BROADCAST_REGISTERED),
    400                 PERMISSION_GRANTED);
    401         waitForResultOrThrow(BROADCAST_TIMEOUT);
    402     }
    403 
    404     public void testRegisteredBroadcastPermissionDenied() throws Exception {
    405         setExpectedReceivers(new String[]{RECEIVER_RESULTS});
    406         registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED), null);
    407         addIntermediate("after-register");
    408 
    409         BroadcastReceiver finish = new BroadcastReceiver() {
    410             public void onReceive(Context context, Intent intent) {
    411                 gotReceive(RECEIVER_RESULTS, intent);
    412             }
    413         };
    414 
    415         getContext().sendOrderedBroadcast(
    416                 makeBroadcastIntent(BROADCAST_REGISTERED),
    417                 PERMISSION_DENIED, finish, null, Activity.RESULT_CANCELED,
    418                 null, null);
    419         waitForResultOrThrow(BROADCAST_TIMEOUT);
    420     }
    421 
    422     public void testLocalReceivePermissionGranted() throws Exception {
    423         setExpectedReceivers(new String[]{RECEIVER_LOCAL});
    424         getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_LOCAL_GRANTED));
    425         waitForResultOrThrow(BROADCAST_TIMEOUT);
    426     }
    427 
    428     public void testLocalReceivePermissionDenied() throws Exception {
    429         setExpectedReceivers(new String[]{RECEIVER_RESULTS});
    430 
    431         BroadcastReceiver finish = new BroadcastReceiver() {
    432             public void onReceive(Context context, Intent intent) {
    433                 gotReceive(RECEIVER_RESULTS, intent);
    434             }
    435         };
    436 
    437         getContext().sendOrderedBroadcast(
    438                 makeBroadcastIntent(BROADCAST_LOCAL_DENIED),
    439                 null, finish, null, Activity.RESULT_CANCELED,
    440                 null, null);
    441         waitForResultOrThrow(BROADCAST_TIMEOUT);
    442     }
    443 
    444     public void testLocalBroadcastPermissionGranted() throws Exception {
    445         setExpectedReceivers(new String[]{RECEIVER_LOCAL});
    446         getContext().sendBroadcast(
    447                 makeBroadcastIntent(BROADCAST_LOCAL),
    448                 PERMISSION_GRANTED);
    449         waitForResultOrThrow(BROADCAST_TIMEOUT);
    450     }
    451 
    452     public void testLocalBroadcastPermissionDenied() throws Exception {
    453         setExpectedReceivers(new String[]{RECEIVER_RESULTS});
    454 
    455         BroadcastReceiver finish = new BroadcastReceiver() {
    456             public void onReceive(Context context, Intent intent) {
    457                 gotReceive(RECEIVER_RESULTS, intent);
    458             }
    459         };
    460 
    461         getContext().sendOrderedBroadcast(
    462                 makeBroadcastIntent(BROADCAST_LOCAL),
    463                 PERMISSION_DENIED, finish, null, Activity.RESULT_CANCELED,
    464                 null, null);
    465         waitForResultOrThrow(BROADCAST_TIMEOUT);
    466     }
    467 
    468     public void testRemoteReceivePermissionGranted() throws Exception {
    469         setExpectedReceivers(new String[]{RECEIVER_REMOTE});
    470         getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_REMOTE_GRANTED));
    471         waitForResultOrThrow(BROADCAST_TIMEOUT);
    472     }
    473 
    474     public void testRemoteReceivePermissionDenied() throws Exception {
    475         setExpectedReceivers(new String[]{RECEIVER_RESULTS});
    476 
    477         BroadcastReceiver finish = new BroadcastReceiver() {
    478             public void onReceive(Context context, Intent intent) {
    479                 gotReceive(RECEIVER_RESULTS, intent);
    480             }
    481         };
    482 
    483         getContext().sendOrderedBroadcast(
    484                 makeBroadcastIntent(BROADCAST_REMOTE_DENIED),
    485                 null, finish, null, Activity.RESULT_CANCELED,
    486                 null, null);
    487         waitForResultOrThrow(BROADCAST_TIMEOUT);
    488     }
    489 
    490     public void testRemoteBroadcastPermissionGranted() throws Exception {
    491         setExpectedReceivers(new String[]{RECEIVER_REMOTE});
    492         getContext().sendBroadcast(
    493                 makeBroadcastIntent(BROADCAST_REMOTE),
    494                 PERMISSION_GRANTED);
    495         waitForResultOrThrow(BROADCAST_TIMEOUT);
    496     }
    497 
    498     public void testRemoteBroadcastPermissionDenied() throws Exception {
    499         setExpectedReceivers(new String[]{RECEIVER_RESULTS});
    500 
    501         BroadcastReceiver finish = new BroadcastReceiver() {
    502             public void onReceive(Context context, Intent intent) {
    503                 gotReceive(RECEIVER_RESULTS, intent);
    504             }
    505         };
    506 
    507         getContext().sendOrderedBroadcast(
    508                 makeBroadcastIntent(BROADCAST_REMOTE),
    509                 PERMISSION_DENIED, finish, null, Activity.RESULT_CANCELED,
    510                 null, null);
    511         waitForResultOrThrow(BROADCAST_TIMEOUT);
    512     }
    513 
    514     public void testReceiverCanNotRegister() throws Exception {
    515         setExpectedReceivers(new String[]{RECEIVER_LOCAL});
    516         getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_FAIL_REGISTER));
    517         waitForResultOrThrow(BROADCAST_TIMEOUT);
    518     }
    519 
    520     public void testReceiverCanNotBind() throws Exception {
    521         setExpectedReceivers(new String[]{RECEIVER_LOCAL});
    522         getContext().sendBroadcast(makeBroadcastIntent(BROADCAST_FAIL_BIND));
    523         waitForResultOrThrow(BROADCAST_TIMEOUT);
    524     }
    525 
    526     public void testLocalUnregisterTwice() throws Exception {
    527         registerMyReceiver(new IntentFilter(BROADCAST_REGISTERED), null);
    528         unregisterMyReceiverNoCheck();
    529         try {
    530             unregisterMyReceiverNoCheck();
    531             fail("No exception thrown on second unregister");
    532         } catch (IllegalArgumentException e) {
    533             Log.i("foo", "Unregister exception", e);
    534         }
    535     }
    536 }
    537