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 BroadcastReceiverTest()63 public BroadcastReceiverTest() { 64 super(TEST_PACKAGE_NAME, MockActivity.class); 65 } 66 67 @Override setUp()68 protected void setUp() throws Exception { 69 super.setUp(); 70 } 71 testConstructor()72 public void testConstructor() { 73 new MockReceiverInternal(); 74 } 75 testAccessDebugUnregister()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 testSetOrderedHint()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 onReceive(Context context, Intent intent)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 hasCalledOnReceive()110 public boolean hasCalledOnReceive() { 111 return mCalledOnReceive; 112 } 113 reset()114 public void reset() { 115 mCalledOnReceive = false; 116 } 117 waitForReceiver(long timeout)118 public synchronized void waitForReceiver(long timeout) 119 throws InterruptedException { 120 if (!mCalledOnReceive) { 121 wait(timeout); 122 } 123 assertTrue(mCalledOnReceive); 124 } 125 waitForReceiverNoException(long timeout)126 public synchronized boolean waitForReceiverNoException(long timeout) 127 throws InterruptedException { 128 if (!mCalledOnReceive) { 129 wait(timeout); 130 } 131 return mCalledOnReceive; 132 } 133 getIBinder()134 public IBinder getIBinder() { 135 return mIBinder; 136 } 137 } 138 139 private class MockReceiverInternalOrder extends MockReceiverInternal { 140 @Override onReceive(Context context, Intent intent)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 MockReceiverInternalVerifyUncalled(int initialCode)152 public MockReceiverInternalVerifyUncalled(int initialCode) { 153 mExpectedInitialCode = initialCode; 154 } 155 156 @Override onReceive(Context context, Intent intent)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 testOnReceive()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 testManifestReceiverPackage()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 testManifestReceiverComponent()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 testManifestReceiverPermission()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 testNoManifestReceiver()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 testAbortBroadcast()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 testDisabledBroadcastReceiver()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 testPeekService()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 testNewPhotoBroadcast_notReceived()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 testNewVideoBroadcast_notReceived()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 onServiceConnected(ComponentName name, IBinder service)401 public synchronized void onServiceConnected(ComponentName name, IBinder service) { 402 serviceConnected = true; 403 notifyAll(); 404 } 405 onServiceDisconnected(ComponentName name)406 public synchronized void onServiceDisconnected(ComponentName name) { 407 } 408 waitForService(long timeout)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