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