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