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