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