Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2009 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.content.cts;
     18 
     19 
     20 import android.app.Service;
     21 import android.content.BroadcastReceiver;
     22 import android.content.ComponentName;
     23 import android.content.Context;
     24 import android.content.Intent;
     25 import android.content.IntentFilter;
     26 import android.content.ServiceConnection;
     27 import android.content.pm.PackageManager;
     28 import android.hardware.Camera;
     29 import android.os.Bundle;
     30 import android.os.IBinder;
     31 import android.platform.test.annotations.AppModeFull;
     32 import android.test.ActivityInstrumentationTestCase2;
     33 
     34 /**
     35  * Test {@link BroadcastReceiver}.
     36  * TODO:  integrate the existing tests.
     37  */
     38 public class BroadcastReceiverTest extends ActivityInstrumentationTestCase2<MockActivity> {
     39     private static final int RESULT_INITIAL_CODE = 1;
     40     private static final String RESULT_INITIAL_DATA = "initial data";
     41 
     42     private static final int RESULT_INTERNAL_FINAL_CODE = 7;
     43     private static final String RESULT_INTERNAL_FINAL_DATA = "internal final data";
     44 
     45     private static final String ACTION_BROADCAST_INTERNAL =
     46             "android.content.cts.BroadcastReceiverTest.BROADCAST_INTERNAL";
     47     private static final String ACTION_BROADCAST_MOCKTEST =
     48             "android.content.cts.BroadcastReceiverTest.BROADCAST_MOCKTEST";
     49     private static final String ACTION_BROADCAST_TESTABORT =
     50             "android.content.cts.BroadcastReceiverTest.BROADCAST_TESTABORT";
     51     private static final String ACTION_BROADCAST_DISABLED =
     52             "android.content.cts.BroadcastReceiverTest.BROADCAST_DISABLED";
     53     private static final String TEST_PACKAGE_NAME = "android.content.cts";
     54 
     55     private static final String SIGNATURE_PERMISSION = "android.content.cts.SIGNATURE_PERMISSION";
     56 
     57     private static final long SEND_BROADCAST_TIMEOUT = 15000;
     58     private static final long START_SERVICE_TIMEOUT  = 3000;
     59 
     60     private static final ComponentName DISABLEABLE_RECEIVER =
     61             new ComponentName("android.content.cts",
     62                     "android.content.cts.MockReceiverDisableable");
     63 
     64     public BroadcastReceiverTest() {
     65         super(TEST_PACKAGE_NAME, MockActivity.class);
     66     }
     67 
     68     @Override
     69     protected void setUp() throws Exception {
     70         super.setUp();
     71     }
     72 
     73     public void testConstructor() {
     74         new MockReceiverInternal();
     75     }
     76 
     77     public void testAccessDebugUnregister() {
     78         MockReceiverInternal mockReceiver = new MockReceiverInternal();
     79         assertFalse(mockReceiver.getDebugUnregister());
     80 
     81         mockReceiver.setDebugUnregister(true);
     82         assertTrue(mockReceiver.getDebugUnregister());
     83 
     84         mockReceiver.setDebugUnregister(false);
     85         assertFalse(mockReceiver.getDebugUnregister());
     86     }
     87 
     88     public void testSetOrderedHint() {
     89         MockReceiverInternal mockReceiver = new MockReceiverInternal();
     90 
     91         /*
     92          * Let's just test to make sure the method doesn't fail for this one.
     93          * It's marked as "for internal use".
     94          */
     95         mockReceiver.setOrderedHint(true);
     96         mockReceiver.setOrderedHint(false);
     97     }
     98 
     99     private class MockReceiverInternal extends BroadcastReceiver  {
    100         protected boolean mCalledOnReceive = false;
    101         private IBinder mIBinder;
    102 
    103         @Override
    104         public synchronized void onReceive(Context context, Intent intent) {
    105             mCalledOnReceive = true;
    106             Intent serviceIntent = new Intent(context, MockService.class);
    107             mIBinder = peekService(context, serviceIntent);
    108             notifyAll();
    109         }
    110 
    111         public boolean hasCalledOnReceive() {
    112             return mCalledOnReceive;
    113         }
    114 
    115         public void reset() {
    116             mCalledOnReceive = false;
    117         }
    118 
    119         public synchronized void waitForReceiver(long timeout)
    120                 throws InterruptedException {
    121             if (!mCalledOnReceive) {
    122                 wait(timeout);
    123             }
    124             assertTrue(mCalledOnReceive);
    125         }
    126 
    127         public synchronized boolean waitForReceiverNoException(long timeout)
    128                 throws InterruptedException {
    129             if (!mCalledOnReceive) {
    130                 wait(timeout);
    131             }
    132             return mCalledOnReceive;
    133         }
    134 
    135         public IBinder getIBinder() {
    136             return mIBinder;
    137         }
    138     }
    139 
    140     private class MockReceiverInternalOrder extends MockReceiverInternal  {
    141         @Override
    142         public synchronized void onReceive(Context context, Intent intent) {
    143             setResultCode(RESULT_INTERNAL_FINAL_CODE);
    144             setResultData(RESULT_INTERNAL_FINAL_DATA);
    145 
    146             super.onReceive(context, intent);
    147         }
    148     }
    149 
    150     private class MockReceiverInternalVerifyUncalled extends MockReceiverInternal {
    151         final int mExpectedInitialCode;
    152 
    153         public MockReceiverInternalVerifyUncalled(int initialCode) {
    154             mExpectedInitialCode = initialCode;
    155         }
    156 
    157         @Override
    158         public synchronized void onReceive(Context context, Intent intent) {
    159             // only update to the expected final values if we're still in the
    160             // initial conditions.  The intermediate receiver would have
    161             // updated the result code if it [inappropriately] ran.
    162             if (getResultCode() == mExpectedInitialCode) {
    163                 setResultCode(RESULT_INTERNAL_FINAL_CODE);
    164             }
    165 
    166             super.onReceive(context, intent);
    167         }
    168     }
    169 
    170     public void testOnReceive () throws InterruptedException {
    171         final MockActivity activity = getActivity();
    172 
    173         MockReceiverInternal internalReceiver = new MockReceiverInternal();
    174         IntentFilter filter = new IntentFilter();
    175         filter.addAction(ACTION_BROADCAST_INTERNAL);
    176         activity.registerReceiver(internalReceiver, filter);
    177 
    178         assertEquals(0, internalReceiver.getResultCode());
    179         assertEquals(null, internalReceiver.getResultData());
    180         assertEquals(null, internalReceiver.getResultExtras(false));
    181 
    182         activity.sendBroadcast(new Intent(ACTION_BROADCAST_INTERNAL)
    183                 .addFlags(Intent.FLAG_RECEIVER_FOREGROUND));
    184         internalReceiver.waitForReceiver(SEND_BROADCAST_TIMEOUT);
    185 
    186         activity.unregisterReceiver(internalReceiver);
    187     }
    188 
    189     @AppModeFull
    190     public void testManifestReceiverPackage() throws InterruptedException {
    191         MockReceiverInternal internalReceiver = new MockReceiverInternal();
    192 
    193         Bundle map = new Bundle();
    194         map.putString(MockReceiver.RESULT_EXTRAS_INVARIABLE_KEY,
    195                 MockReceiver.RESULT_EXTRAS_INVARIABLE_VALUE);
    196         map.putString(MockReceiver.RESULT_EXTRAS_REMOVE_KEY,
    197                 MockReceiver.RESULT_EXTRAS_REMOVE_VALUE);
    198         getInstrumentation().getContext().sendOrderedBroadcast(
    199                 new Intent(ACTION_BROADCAST_MOCKTEST)
    200                         .setPackage(TEST_PACKAGE_NAME).addFlags(Intent.FLAG_RECEIVER_FOREGROUND),
    201                 null, internalReceiver,
    202                 null, RESULT_INITIAL_CODE, RESULT_INITIAL_DATA, map);
    203         internalReceiver.waitForReceiver(SEND_BROADCAST_TIMEOUT);
    204 
    205         // These are set by MockReceiver.
    206         assertEquals(MockReceiver.RESULT_CODE, internalReceiver.getResultCode());
    207         assertEquals(MockReceiver.RESULT_DATA, internalReceiver.getResultData());
    208 
    209         Bundle resultExtras = internalReceiver.getResultExtras(false);
    210         assertEquals(MockReceiver.RESULT_EXTRAS_INVARIABLE_VALUE,
    211                 resultExtras.getString(MockReceiver.RESULT_EXTRAS_INVARIABLE_KEY));
    212         assertEquals(MockReceiver.RESULT_EXTRAS_ADD_VALUE,
    213                 resultExtras.getString(MockReceiver.RESULT_EXTRAS_ADD_KEY));
    214         assertNull(resultExtras.getString(MockReceiver.RESULT_EXTRAS_REMOVE_KEY));
    215     }
    216 
    217     @AppModeFull
    218     public void testManifestReceiverComponent() throws InterruptedException {
    219         MockReceiverInternal internalReceiver = new MockReceiverInternal();
    220 
    221         Bundle map = new Bundle();
    222         map.putString(MockReceiver.RESULT_EXTRAS_INVARIABLE_KEY,
    223                 MockReceiver.RESULT_EXTRAS_INVARIABLE_VALUE);
    224         map.putString(MockReceiver.RESULT_EXTRAS_REMOVE_KEY,
    225                 MockReceiver.RESULT_EXTRAS_REMOVE_VALUE);
    226         getInstrumentation().getContext().sendOrderedBroadcast(
    227                 new Intent(ACTION_BROADCAST_MOCKTEST)
    228                         .setClass(getActivity(), MockReceiver.class)
    229                         .addFlags(Intent.FLAG_RECEIVER_FOREGROUND),
    230                 null, internalReceiver,
    231                 null, RESULT_INITIAL_CODE, RESULT_INITIAL_DATA, map);
    232         internalReceiver.waitForReceiver(SEND_BROADCAST_TIMEOUT);
    233 
    234         // These are set by MockReceiver.
    235         assertEquals(MockReceiver.RESULT_CODE, internalReceiver.getResultCode());
    236         assertEquals(MockReceiver.RESULT_DATA, internalReceiver.getResultData());
    237 
    238         Bundle resultExtras = internalReceiver.getResultExtras(false);
    239         assertEquals(MockReceiver.RESULT_EXTRAS_INVARIABLE_VALUE,
    240                 resultExtras.getString(MockReceiver.RESULT_EXTRAS_INVARIABLE_KEY));
    241         assertEquals(MockReceiver.RESULT_EXTRAS_ADD_VALUE,
    242                 resultExtras.getString(MockReceiver.RESULT_EXTRAS_ADD_KEY));
    243         assertNull(resultExtras.getString(MockReceiver.RESULT_EXTRAS_REMOVE_KEY));
    244     }
    245 
    246     @AppModeFull
    247     public void testManifestReceiverPermission() throws InterruptedException {
    248         MockReceiverInternal internalReceiver = new MockReceiverInternal();
    249 
    250         Bundle map = new Bundle();
    251         map.putString(MockReceiver.RESULT_EXTRAS_INVARIABLE_KEY,
    252                 MockReceiver.RESULT_EXTRAS_INVARIABLE_VALUE);
    253         map.putString(MockReceiver.RESULT_EXTRAS_REMOVE_KEY,
    254                 MockReceiver.RESULT_EXTRAS_REMOVE_VALUE);
    255         getInstrumentation().getContext().sendOrderedBroadcast(
    256                 new Intent(ACTION_BROADCAST_MOCKTEST)
    257                         .addFlags(Intent.FLAG_RECEIVER_FOREGROUND),
    258                 SIGNATURE_PERMISSION, internalReceiver,
    259                 null, RESULT_INITIAL_CODE, RESULT_INITIAL_DATA, map);
    260         internalReceiver.waitForReceiver(SEND_BROADCAST_TIMEOUT);
    261 
    262         // These are set by MockReceiver.
    263         assertEquals(MockReceiver.RESULT_CODE, internalReceiver.getResultCode());
    264         assertEquals(MockReceiver.RESULT_DATA, internalReceiver.getResultData());
    265 
    266         Bundle resultExtras = internalReceiver.getResultExtras(false);
    267         assertEquals(MockReceiver.RESULT_EXTRAS_INVARIABLE_VALUE,
    268                 resultExtras.getString(MockReceiver.RESULT_EXTRAS_INVARIABLE_KEY));
    269         assertEquals(MockReceiver.RESULT_EXTRAS_ADD_VALUE,
    270                 resultExtras.getString(MockReceiver.RESULT_EXTRAS_ADD_KEY));
    271         assertNull(resultExtras.getString(MockReceiver.RESULT_EXTRAS_REMOVE_KEY));
    272     }
    273 
    274     public void testNoManifestReceiver() throws InterruptedException {
    275         MockReceiverInternal internalReceiver = new MockReceiverInternal();
    276 
    277         Bundle map = new Bundle();
    278         map.putString(MockReceiver.RESULT_EXTRAS_INVARIABLE_KEY,
    279                 MockReceiver.RESULT_EXTRAS_INVARIABLE_VALUE);
    280         map.putString(MockReceiver.RESULT_EXTRAS_REMOVE_KEY,
    281                 MockReceiver.RESULT_EXTRAS_REMOVE_VALUE);
    282         getInstrumentation().getContext().sendOrderedBroadcast(
    283                 new Intent(ACTION_BROADCAST_MOCKTEST).addFlags(Intent.FLAG_RECEIVER_FOREGROUND),
    284                 null, internalReceiver,
    285                 null, RESULT_INITIAL_CODE, RESULT_INITIAL_DATA, map);
    286         internalReceiver.waitForReceiver(SEND_BROADCAST_TIMEOUT);
    287 
    288         // The MockReceiver should not have run, so we should still have the initial result.
    289         assertEquals(RESULT_INITIAL_CODE, internalReceiver.getResultCode());
    290         assertEquals(RESULT_INITIAL_DATA, internalReceiver.getResultData());
    291 
    292         Bundle resultExtras = internalReceiver.getResultExtras(false);
    293         assertEquals(MockReceiver.RESULT_EXTRAS_INVARIABLE_VALUE,
    294                 resultExtras.getString(MockReceiver.RESULT_EXTRAS_INVARIABLE_KEY));
    295         assertNull(resultExtras.getString(MockReceiver.RESULT_EXTRAS_ADD_KEY));
    296         assertEquals(MockReceiver.RESULT_EXTRAS_REMOVE_VALUE,
    297                 resultExtras.getString(MockReceiver.RESULT_EXTRAS_REMOVE_KEY));
    298     }
    299 
    300     @AppModeFull
    301     public void testAbortBroadcast() throws InterruptedException {
    302         MockReceiverInternalOrder internalOrderReceiver = new MockReceiverInternalOrder();
    303 
    304         assertEquals(0, internalOrderReceiver.getResultCode());
    305         assertNull(internalOrderReceiver.getResultData());
    306         assertNull(internalOrderReceiver.getResultExtras(false));
    307 
    308         Bundle map = new Bundle();
    309         map.putString(MockReceiver.RESULT_EXTRAS_INVARIABLE_KEY,
    310                 MockReceiver.RESULT_EXTRAS_INVARIABLE_VALUE);
    311         map.putString(MockReceiver.RESULT_EXTRAS_REMOVE_KEY,
    312                 MockReceiver.RESULT_EXTRAS_REMOVE_VALUE);
    313         // The order of the receiver is:
    314         // MockReceiverFirst --> MockReceiverAbort --> MockReceiver --> internalOrderReceiver.
    315         // And MockReceiver is the receiver which will be aborted.
    316         getInstrumentation().getContext().sendOrderedBroadcast(
    317                 new Intent(ACTION_BROADCAST_TESTABORT)
    318                         .setPackage(TEST_PACKAGE_NAME).addFlags(Intent.FLAG_RECEIVER_FOREGROUND),
    319                 null, internalOrderReceiver,
    320                 null, RESULT_INITIAL_CODE, RESULT_INITIAL_DATA, map);
    321         internalOrderReceiver.waitForReceiver(SEND_BROADCAST_TIMEOUT);
    322 
    323         assertEquals(RESULT_INTERNAL_FINAL_CODE, internalOrderReceiver.getResultCode());
    324         assertEquals(RESULT_INTERNAL_FINAL_DATA, internalOrderReceiver.getResultData());
    325         Bundle resultExtras = internalOrderReceiver.getResultExtras(false);
    326         assertEquals(MockReceiver.RESULT_EXTRAS_INVARIABLE_VALUE,
    327                 resultExtras.getString(MockReceiver.RESULT_EXTRAS_INVARIABLE_KEY));
    328         assertEquals(MockReceiver.RESULT_EXTRAS_REMOVE_VALUE,
    329                 resultExtras.getString(MockReceiver.RESULT_EXTRAS_REMOVE_KEY));
    330         assertEquals(MockReceiverFirst.RESULT_EXTRAS_FIRST_VALUE,
    331                 resultExtras.getString(MockReceiverFirst.RESULT_EXTRAS_FIRST_KEY));
    332         assertEquals(MockReceiverAbort.RESULT_EXTRAS_ABORT_VALUE,
    333                 resultExtras.getString(MockReceiverAbort.RESULT_EXTRAS_ABORT_KEY));
    334     }
    335 
    336     public void testDisabledBroadcastReceiver() throws Exception {
    337         final Context context = getInstrumentation().getContext();
    338         PackageManager pm = context.getPackageManager();
    339 
    340         MockReceiverInternalVerifyUncalled lastReceiver =
    341                 new MockReceiverInternalVerifyUncalled(RESULT_INITIAL_CODE);
    342         assertEquals(0, lastReceiver.getResultCode());
    343 
    344         pm.setComponentEnabledSetting(DISABLEABLE_RECEIVER,
    345                 PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
    346                 PackageManager.DONT_KILL_APP);
    347 
    348         context.sendOrderedBroadcast(
    349                 new Intent(ACTION_BROADCAST_DISABLED).addFlags(Intent.FLAG_RECEIVER_FOREGROUND),
    350                 null, lastReceiver,
    351                 null, RESULT_INITIAL_CODE, RESULT_INITIAL_DATA, new Bundle());
    352         lastReceiver.waitForReceiver(SEND_BROADCAST_TIMEOUT);
    353 
    354         assertEquals(RESULT_INTERNAL_FINAL_CODE, lastReceiver.getResultCode());
    355     }
    356 
    357     public void testPeekService() throws InterruptedException {
    358         final MockActivity activity = getActivity();
    359 
    360         MockReceiverInternal internalReceiver = new MockReceiverInternal();
    361         IntentFilter filter = new IntentFilter();
    362         filter.addAction(ACTION_BROADCAST_INTERNAL);
    363         activity.registerReceiver(internalReceiver, filter);
    364 
    365         activity.sendBroadcast(new Intent(ACTION_BROADCAST_INTERNAL)
    366                 .addFlags(Intent.FLAG_RECEIVER_FOREGROUND));
    367         internalReceiver.waitForReceiver(SEND_BROADCAST_TIMEOUT);
    368         assertNull(internalReceiver.getIBinder());
    369 
    370         Intent intent = new Intent(activity, MockService.class);
    371         MyServiceConnection msc = new MyServiceConnection();
    372         assertTrue(activity.bindService(intent, msc, Service.BIND_AUTO_CREATE));
    373         assertTrue(msc.waitForService(START_SERVICE_TIMEOUT));
    374 
    375         internalReceiver.reset();
    376         activity.sendBroadcast(new Intent(ACTION_BROADCAST_INTERNAL)
    377                 .addFlags(Intent.FLAG_RECEIVER_FOREGROUND));
    378         internalReceiver.waitForReceiver(SEND_BROADCAST_TIMEOUT);
    379         assertNotNull(internalReceiver.getIBinder());
    380         activity.unbindService(msc);
    381         activity.stopService(intent);
    382         activity.unregisterReceiver(internalReceiver);
    383     }
    384 
    385     public void testNewPhotoBroadcast_notReceived() throws InterruptedException {
    386         final MockActivity activity = getActivity();
    387         MockReceiverInternal internalReceiver = new MockReceiverInternal();
    388         IntentFilter filter = new IntentFilter();
    389         filter.addAction(Camera.ACTION_NEW_PICTURE);
    390         activity.registerReceiver(internalReceiver, filter);
    391         assertFalse(internalReceiver.waitForReceiverNoException(SEND_BROADCAST_TIMEOUT));
    392     }
    393 
    394     public void testNewVideoBroadcast_notReceived() throws InterruptedException {
    395         final MockActivity activity = getActivity();
    396         MockReceiverInternal internalReceiver = new MockReceiverInternal();
    397         IntentFilter filter = new IntentFilter();
    398         filter.addAction(Camera.ACTION_NEW_VIDEO);
    399         activity.registerReceiver(internalReceiver, filter);
    400         assertFalse(internalReceiver.waitForReceiverNoException(SEND_BROADCAST_TIMEOUT));
    401     }
    402 
    403     static class MyServiceConnection implements ServiceConnection {
    404         private boolean serviceConnected;
    405 
    406         public synchronized void onServiceConnected(ComponentName name, IBinder service) {
    407             serviceConnected = true;
    408             notifyAll();
    409         }
    410 
    411         public synchronized void onServiceDisconnected(ComponentName name) {
    412         }
    413 
    414         public synchronized boolean waitForService(long timeout) {
    415             if (!serviceConnected) {
    416                 try {
    417                     wait(timeout);
    418                 } catch (InterruptedException ignored) {
    419                     // ignored
    420                 }
    421             }
    422             return serviceConnected;
    423         }
    424     }
    425 }
    426