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