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