Home | History | Annotate | Download | only in cts
      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