1 /* 2 * Copyright (C) 2008 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.cts; 18 19 import android.app.PendingIntent; 20 import android.app.PendingIntent.CanceledException; 21 import android.app.stubs.MockReceiver; 22 import android.app.stubs.MockService; 23 import android.app.stubs.PendingIntentStubActivity; 24 import android.content.Context; 25 import android.content.Intent; 26 import android.os.Bundle; 27 import android.os.Handler; 28 import android.os.Looper; 29 import android.os.Message; 30 import android.os.Parcel; 31 import android.os.SystemClock; 32 import android.test.AndroidTestCase; 33 import android.util.Log; 34 35 public class PendingIntentTest extends AndroidTestCase { 36 37 private static final int WAIT_TIME = 10000; 38 private PendingIntent mPendingIntent; 39 private Intent mIntent; 40 private Context mContext; 41 private boolean mFinishResult; 42 private boolean mHandleResult; 43 private String mResultAction; 44 private PendingIntent.OnFinished mFinish; 45 private boolean mLooperStart; 46 private Looper mLooper; 47 private Handler mHandler; 48 49 @Override 50 protected void setUp() throws Exception { 51 super.setUp(); 52 mContext = getContext(); 53 mFinish = new PendingIntent.OnFinished() { 54 public void onSendFinished(PendingIntent pi, Intent intent, int resultCode, 55 String resultData, Bundle resultExtras) { 56 synchronized (mFinish) { 57 mFinishResult = true; 58 if (intent != null) { 59 mResultAction = intent.getAction(); 60 } 61 mFinish.notifyAll(); 62 } 63 } 64 }; 65 66 new Thread() { 67 @Override 68 public void run() { 69 Looper.prepare(); 70 mLooper = Looper.myLooper(); 71 mLooperStart = true; 72 Looper.loop(); 73 } 74 }.start(); 75 while (!mLooperStart) { 76 Thread.sleep(50); 77 } 78 mHandler = new Handler(mLooper) { 79 @Override 80 public void dispatchMessage(Message msg) { 81 synchronized (mFinish) { 82 mHandleResult = true; 83 } 84 super.dispatchMessage(msg); 85 } 86 87 @Override 88 public boolean sendMessageAtTime(Message msg, long uptimeMillis) { 89 synchronized (mFinish) { 90 mHandleResult = true; 91 } 92 return super.sendMessageAtTime(msg, uptimeMillis); 93 } 94 95 @Override 96 public void handleMessage(Message msg) { 97 synchronized (mFinish) { 98 mHandleResult = true; 99 } 100 super.handleMessage(msg); 101 } 102 }; 103 } 104 105 @Override 106 protected void tearDown() throws Exception { 107 super.tearDown(); 108 mLooper.quit(); 109 } 110 111 private void prepareFinish() { 112 synchronized (mFinish) { 113 mFinishResult = false; 114 mHandleResult = false; 115 } 116 } 117 118 public boolean waitForFinish(long timeout) { 119 long now = SystemClock.elapsedRealtime(); 120 final long endTime = now + timeout; 121 synchronized (mFinish) { 122 while (!mFinishResult && now < endTime) { 123 try { 124 mFinish.wait(endTime - now); 125 } catch (InterruptedException e) { 126 } 127 now = SystemClock.elapsedRealtime(); 128 } 129 return mFinishResult; 130 } 131 } 132 133 public void testGetActivity() throws InterruptedException, CanceledException { 134 PendingIntentStubActivity.prepare(); 135 mPendingIntent = null; 136 mIntent = new Intent(); 137 138 mIntent.setClass(mContext, PendingIntentStubActivity.class); 139 mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 140 mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent, 141 PendingIntent.FLAG_CANCEL_CURRENT); 142 assertEquals(mContext.getPackageName(), mPendingIntent.getTargetPackage()); 143 144 mPendingIntent.send(); 145 146 PendingIntentStubActivity.waitForCreate(WAIT_TIME); 147 assertNotNull(mPendingIntent); 148 assertEquals(PendingIntentStubActivity.status, PendingIntentStubActivity.ON_CREATE); 149 150 // test getActivity return null 151 mPendingIntent.cancel(); 152 mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent, 153 PendingIntent.FLAG_NO_CREATE); 154 assertNull(mPendingIntent); 155 156 mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent, 157 PendingIntent.FLAG_ONE_SHOT); 158 159 pendingIntentSendError(mPendingIntent); 160 } 161 162 private void pendingIntentSendError(PendingIntent pendingIntent) { 163 try { 164 // From the doc send function will throw CanceledException if the PendingIntent 165 // is no longer allowing more intents to be sent through it. So here call it twice then 166 // a CanceledException should be caught. 167 mPendingIntent.send(); 168 mPendingIntent.send(); 169 fail("CanceledException expected, but not thrown"); 170 } catch (PendingIntent.CanceledException e) { 171 // expected 172 } 173 } 174 175 public void testGetBroadcast() throws InterruptedException, CanceledException { 176 MockReceiver.prepareReceive(null, 0); 177 mIntent = new Intent(MockReceiver.MOCKACTION); 178 mIntent.setClass(mContext, MockReceiver.class); 179 mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 180 PendingIntent.FLAG_CANCEL_CURRENT); 181 182 mPendingIntent.send(); 183 184 MockReceiver.waitForReceive(WAIT_TIME); 185 assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction); 186 187 // test getBroadcast return null 188 mPendingIntent.cancel(); 189 mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 190 PendingIntent.FLAG_NO_CREATE); 191 assertNull(mPendingIntent); 192 193 mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 194 PendingIntent.FLAG_ONE_SHOT); 195 196 pendingIntentSendError(mPendingIntent); 197 } 198 199 public void testGetService() throws InterruptedException, CanceledException { 200 MockService.prepareStart(); 201 mIntent = new Intent(); 202 mIntent.setClass(mContext, MockService.class); 203 mPendingIntent = PendingIntent.getService(mContext, 1, mIntent, 204 PendingIntent.FLAG_CANCEL_CURRENT); 205 206 mPendingIntent.send(); 207 208 MockService.waitForStart(WAIT_TIME); 209 assertTrue(MockService.result); 210 211 // test getService return null 212 mPendingIntent.cancel(); 213 mPendingIntent = PendingIntent.getService(mContext, 1, mIntent, 214 PendingIntent.FLAG_NO_CREATE); 215 assertNull(mPendingIntent); 216 217 mPendingIntent = PendingIntent.getService(mContext, 1, mIntent, 218 PendingIntent.FLAG_ONE_SHOT); 219 220 pendingIntentSendError(mPendingIntent); 221 } 222 223 public void testStartServiceOnFinishedHandler() throws InterruptedException, CanceledException { 224 MockService.prepareStart(); 225 prepareFinish(); 226 mIntent = new Intent(); 227 mIntent.setClass(mContext, MockService.class); 228 mPendingIntent = PendingIntent.getService(mContext, 1, mIntent, 229 PendingIntent.FLAG_CANCEL_CURRENT); 230 231 mPendingIntent.send(mContext, 1, null, mFinish, null); 232 233 MockService.waitForStart(WAIT_TIME); 234 waitForFinish(WAIT_TIME); 235 assertTrue(MockService.result); 236 237 assertTrue(mFinishResult); 238 assertFalse(mHandleResult); 239 mPendingIntent.cancel(); 240 241 MockService.prepareStart(); 242 prepareFinish(); 243 mIntent = new Intent(); 244 mIntent.setClass(mContext, MockService.class); 245 mPendingIntent = PendingIntent.getService(mContext, 1, mIntent, 246 PendingIntent.FLAG_CANCEL_CURRENT); 247 248 mPendingIntent.send(mContext, 1, null, mFinish, mHandler); 249 250 MockService.waitForStart(WAIT_TIME); 251 waitForFinish(WAIT_TIME); 252 assertTrue(MockService.result); 253 254 assertTrue(mFinishResult); 255 assertTrue(mHandleResult); 256 mPendingIntent.cancel(); 257 258 } 259 260 public void testCancel() throws CanceledException { 261 mIntent = new Intent(); 262 mIntent.setClass(mContext, MockService.class); 263 mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 264 PendingIntent.FLAG_CANCEL_CURRENT); 265 266 mPendingIntent.send(); 267 268 mPendingIntent.cancel(); 269 pendingIntentSendShouldFail(mPendingIntent); 270 } 271 272 private void pendingIntentSendShouldFail(PendingIntent pendingIntent) { 273 try { 274 pendingIntent.send(); 275 fail("CanceledException expected, but not thrown"); 276 } catch (CanceledException e) { 277 // expected 278 } 279 } 280 281 public void testSend() throws InterruptedException, CanceledException { 282 MockReceiver.prepareReceive(null, -1); 283 mIntent = new Intent(); 284 mIntent.setAction(MockReceiver.MOCKACTION); 285 mIntent.setClass(mContext, MockReceiver.class); 286 mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 287 PendingIntent.FLAG_CANCEL_CURRENT); 288 289 mPendingIntent.send(); 290 291 MockReceiver.waitForReceive(WAIT_TIME); 292 293 // send function to send default code 0 294 assertEquals(0, MockReceiver.sResultCode); 295 assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction); 296 mPendingIntent.cancel(); 297 298 pendingIntentSendShouldFail(mPendingIntent); 299 } 300 301 public void testSendWithParamInt() throws InterruptedException, CanceledException { 302 mIntent = new Intent(MockReceiver.MOCKACTION); 303 mIntent.setClass(mContext, MockReceiver.class); 304 mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 305 PendingIntent.FLAG_CANCEL_CURRENT); 306 MockReceiver.prepareReceive(null, 0); 307 // send result code 1. 308 mPendingIntent.send(1); 309 MockReceiver.waitForReceive(WAIT_TIME); 310 assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction); 311 312 // assert the result code 313 assertEquals(1, MockReceiver.sResultCode); 314 assertEquals(mResultAction, null); 315 316 MockReceiver.prepareReceive(null, 0); 317 // send result code 2 318 mPendingIntent.send(2); 319 MockReceiver.waitForReceive(WAIT_TIME); 320 321 assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction); 322 323 // assert the result code 324 assertEquals(2, MockReceiver.sResultCode); 325 assertEquals(MockReceiver.sAction, MockReceiver.MOCKACTION); 326 assertNull(mResultAction); 327 mPendingIntent.cancel(); 328 pendingIntentSendShouldFail(mPendingIntent); 329 } 330 331 public void testSendWithParamContextIntIntent() throws InterruptedException, CanceledException { 332 mIntent = new Intent(MockReceiver.MOCKACTION); 333 mIntent.setClass(mContext, MockReceiver.class); 334 335 MockReceiver.prepareReceive(null, 0); 336 337 mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1); 338 339 mPendingIntent.send(mContext, 1, null); 340 MockReceiver.waitForReceive(WAIT_TIME); 341 342 assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction); 343 assertEquals(1, MockReceiver.sResultCode); 344 mPendingIntent.cancel(); 345 346 mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1); 347 MockReceiver.prepareReceive(null, 0); 348 349 mPendingIntent.send(mContext, 2, mIntent); 350 MockReceiver.waitForReceive(WAIT_TIME); 351 assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction); 352 assertEquals(2, MockReceiver.sResultCode); 353 mPendingIntent.cancel(); 354 } 355 356 public void testSendWithParamIntOnFinishedHandler() throws InterruptedException, 357 CanceledException { 358 mIntent = new Intent(MockReceiver.MOCKACTION); 359 mIntent.setClass(mContext, MockReceiver.class); 360 361 mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1); 362 MockReceiver.prepareReceive(null, 0); 363 prepareFinish(); 364 365 mPendingIntent.send(1, null, null); 366 MockReceiver.waitForReceive(WAIT_TIME); 367 assertFalse(mFinishResult); 368 assertFalse(mHandleResult); 369 assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction); 370 371 // assert result code 372 assertEquals(1, MockReceiver.sResultCode); 373 mPendingIntent.cancel(); 374 375 mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1); 376 MockReceiver.prepareReceive(null, 0); 377 prepareFinish(); 378 379 mPendingIntent.send(2, mFinish, null); 380 waitForFinish(WAIT_TIME); 381 assertTrue(mFinishResult); 382 assertFalse(mHandleResult); 383 assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction); 384 385 // assert result code 386 assertEquals(2, MockReceiver.sResultCode); 387 mPendingIntent.cancel(); 388 389 MockReceiver.prepareReceive(null, 0); 390 prepareFinish(); 391 mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1); 392 mPendingIntent.send(3, mFinish, mHandler); 393 waitForFinish(WAIT_TIME); 394 assertTrue(mHandleResult); 395 assertTrue(mFinishResult); 396 assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction); 397 398 // assert result code 399 assertEquals(3, MockReceiver.sResultCode); 400 mPendingIntent.cancel(); 401 } 402 403 public void testSendWithParamContextIntIntentOnFinishedHandler() throws InterruptedException, 404 CanceledException { 405 mIntent = new Intent(MockReceiver.MOCKACTION); 406 mIntent.setAction(MockReceiver.MOCKACTION); 407 mIntent.setClass(getContext(), MockReceiver.class); 408 409 mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1); 410 MockReceiver.prepareReceive(null, 0); 411 prepareFinish(); 412 mPendingIntent.send(mContext, 1, mIntent, null, null); 413 MockReceiver.waitForReceive(WAIT_TIME); 414 assertFalse(mFinishResult); 415 assertFalse(mHandleResult); 416 assertNull(mResultAction); 417 assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction); 418 mPendingIntent.cancel(); 419 420 mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1); 421 MockReceiver.prepareReceive(null, 0); 422 prepareFinish(); 423 mPendingIntent.send(mContext, 1, mIntent, mFinish, null); 424 waitForFinish(WAIT_TIME); 425 assertTrue(mFinishResult); 426 assertEquals(mResultAction, MockReceiver.MOCKACTION); 427 assertFalse(mHandleResult); 428 assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction); 429 mPendingIntent.cancel(); 430 431 mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1); 432 MockReceiver.prepareReceive(null, 0); 433 prepareFinish(); 434 mPendingIntent.send(mContext, 1, mIntent, mFinish, mHandler); 435 waitForFinish(WAIT_TIME); 436 assertTrue(mHandleResult); 437 assertEquals(mResultAction, MockReceiver.MOCKACTION); 438 assertTrue(mFinishResult); 439 assertEquals(MockReceiver.MOCKACTION, MockReceiver.sAction); 440 mPendingIntent.cancel(); 441 } 442 443 444 public void testSendNoReceiverOnFinishedHandler() throws InterruptedException, 445 CanceledException { 446 // This action won't match anything, so no receiver will run but we should 447 // still get a finish result. 448 final String BAD_ACTION = MockReceiver.MOCKACTION + "_bad"; 449 mIntent = new Intent(BAD_ACTION); 450 mIntent.setAction(BAD_ACTION); 451 452 mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1); 453 MockReceiver.prepareReceive(null, 0); 454 prepareFinish(); 455 mPendingIntent.send(mContext, 1, mIntent, mFinish, null); 456 waitForFinish(WAIT_TIME); 457 assertTrue(mFinishResult); 458 assertEquals(mResultAction, BAD_ACTION); 459 assertFalse(mHandleResult); 460 assertNull(MockReceiver.sAction); 461 mPendingIntent.cancel(); 462 463 mPendingIntent = PendingIntent.getBroadcast(mContext, 1, mIntent, 1); 464 MockReceiver.prepareReceive(null, 0); 465 prepareFinish(); 466 mPendingIntent.send(mContext, 1, mIntent, mFinish, mHandler); 467 waitForFinish(WAIT_TIME); 468 assertTrue(mHandleResult); 469 assertEquals(mResultAction, BAD_ACTION); 470 assertTrue(mFinishResult); 471 assertNull(MockReceiver.sAction); 472 mPendingIntent.cancel(); 473 } 474 475 public void testGetTargetPackage() { 476 mIntent = new Intent(); 477 mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent, 478 PendingIntent.FLAG_CANCEL_CURRENT); 479 assertEquals(mContext.getPackageName(), mPendingIntent.getTargetPackage()); 480 } 481 482 public void testEquals() { 483 mIntent = new Intent(); 484 mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent, 485 PendingIntent.FLAG_CANCEL_CURRENT); 486 487 PendingIntent target = PendingIntent.getActivity(mContext, 1, mIntent, 488 PendingIntent.FLAG_CANCEL_CURRENT); 489 490 assertFalse(mPendingIntent.equals(target)); 491 assertFalse(mPendingIntent.hashCode() == target.hashCode()); 492 mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent, 1); 493 494 target = PendingIntent.getActivity(mContext, 1, mIntent, 1); 495 assertTrue(mPendingIntent.equals(target)); 496 497 mIntent = new Intent(MockReceiver.MOCKACTION); 498 target = PendingIntent.getBroadcast(mContext, 1, mIntent, 1); 499 assertFalse(mPendingIntent.equals(target)); 500 assertFalse(mPendingIntent.hashCode() == target.hashCode()); 501 502 mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent, 1); 503 target = PendingIntent.getActivity(mContext, 1, mIntent, 1); 504 505 assertTrue(mPendingIntent.equals(target)); 506 assertEquals(mPendingIntent.hashCode(), target.hashCode()); 507 } 508 509 public void testDescribeContents() { 510 mIntent = new Intent(); 511 mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent, 512 PendingIntent.FLAG_CANCEL_CURRENT); 513 final int expected = 0; 514 assertEquals(expected, mPendingIntent.describeContents()); 515 } 516 517 public void testWriteToParcel() { 518 mIntent = new Intent(); 519 mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent, 520 PendingIntent.FLAG_CANCEL_CURRENT); 521 Parcel parcel = Parcel.obtain(); 522 523 mPendingIntent.writeToParcel(parcel, 0); 524 parcel.setDataPosition(0); 525 PendingIntent pendingIntent = PendingIntent.CREATOR.createFromParcel(parcel); 526 assertTrue(mPendingIntent.equals(pendingIntent)); 527 } 528 529 public void testReadAndWritePendingIntentOrNullToParcel() { 530 mIntent = new Intent(); 531 mPendingIntent = PendingIntent.getActivity(mContext, 1, mIntent, 532 PendingIntent.FLAG_CANCEL_CURRENT); 533 assertNotNull(mPendingIntent.toString()); 534 535 Parcel parcel = Parcel.obtain(); 536 PendingIntent.writePendingIntentOrNullToParcel(mPendingIntent, parcel); 537 parcel.setDataPosition(0); 538 PendingIntent target = PendingIntent.readPendingIntentOrNullFromParcel(parcel); 539 assertEquals(mPendingIntent, target); 540 assertEquals(mPendingIntent.getTargetPackage(), target.getTargetPackage()); 541 542 mPendingIntent = null; 543 parcel = Parcel.obtain(); 544 PendingIntent.writePendingIntentOrNullToParcel(mPendingIntent, parcel); 545 target = PendingIntent.readPendingIntentOrNullFromParcel(parcel); 546 assertNull(target); 547 } 548 549 } 550