Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2009 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.Activity;
     20 import android.app.Instrumentation;
     21 import android.app.Instrumentation.ActivityMonitor;
     22 import android.app.Instrumentation.ActivityResult;
     23 import android.app.stubs.ActivityMonitorTestActivity;
     24 import android.app.stubs.InstrumentationTestActivity;
     25 import android.content.Context;
     26 import android.content.Intent;
     27 import android.content.IntentFilter;
     28 import android.test.InstrumentationTestCase;
     29 import android.util.Log;
     30 
     31 import java.util.concurrent.CountDownLatch;
     32 import java.util.concurrent.TimeUnit;
     33 
     34 public class Instrumentation_ActivityMonitorTest extends InstrumentationTestCase {
     35     private static final String TAG = "ActivityMonitorTest";
     36 
     37     private static final long TIMEOUT_FOR_ACTIVITY_LAUNCH_MS = 5000; // 5 sec
     38     private static final long CHECK_INTERVAL_FOR_ACTIVITY_LAUNCH_MS = 100; // 0.1 sec
     39 
     40     /**
     41      * check points:
     42      * 1 Constructor with blocking true and false
     43      * 2 waitForActivity with timeout and no timeout
     44      * 3 get info about ActivityMonitor
     45      */
     46     public void testActivityMonitor() throws Exception {
     47         ActivityResult result = new ActivityResult(Activity.RESULT_OK, new Intent());
     48         Instrumentation instrumentation = getInstrumentation();
     49         ActivityMonitor am = instrumentation.addMonitor(
     50                 InstrumentationTestActivity.class.getName(), result, false);
     51         Context context = instrumentation.getTargetContext();
     52         Intent intent = new Intent(context, InstrumentationTestActivity.class);
     53         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
     54         context.startActivity(intent);
     55         Activity lastActivity = am.getLastActivity();
     56         long timeout = System.currentTimeMillis() + TIMEOUT_FOR_ACTIVITY_LAUNCH_MS;
     57         while (lastActivity == null && System.currentTimeMillis() < timeout) {
     58             Thread.sleep(CHECK_INTERVAL_FOR_ACTIVITY_LAUNCH_MS);
     59             lastActivity = am.getLastActivity();
     60         }
     61         Activity activity = am.waitForActivity();
     62         assertSame(activity, lastActivity);
     63         assertEquals(1, am.getHits());
     64         assertTrue(activity instanceof InstrumentationTestActivity);
     65         activity.finish();
     66         instrumentation.waitForIdleSync();
     67         context.startActivity(intent);
     68         timeout = System.currentTimeMillis() + TIMEOUT_FOR_ACTIVITY_LAUNCH_MS;
     69         activity = null;
     70         while (activity == null && System.currentTimeMillis() < timeout) {
     71             Thread.sleep(CHECK_INTERVAL_FOR_ACTIVITY_LAUNCH_MS);
     72             activity = am.waitForActivityWithTimeout(CHECK_INTERVAL_FOR_ACTIVITY_LAUNCH_MS);
     73         }
     74         assertNotNull(activity);
     75         activity.finish();
     76         instrumentation.removeMonitor(am);
     77 
     78         am = new ActivityMonitor(InstrumentationTestActivity.class.getName(), result, true);
     79         assertSame(result, am.getResult());
     80         assertTrue(am.isBlocking());
     81         IntentFilter which = new IntentFilter();
     82         am = new ActivityMonitor(which, result, false);
     83         assertSame(which, am.getFilter());
     84         assertFalse(am.isBlocking());
     85     }
     86 
     87     /**
     88      * Verifies that
     89      *   - when ActivityMonitor.onStartActivity returs non-null, then there is monitor hit.
     90      *   - when ActivityMonitor.onStartActivity returns null, then the activity start is not blocked.
     91      */
     92     public void testActivityMonitor_onStartActivity() throws Exception {
     93         final ActivityResult result = new ActivityResult(Activity.RESULT_OK, new Intent());
     94         final Instrumentation instrumentation = getInstrumentation();
     95         final Context context = instrumentation.getTargetContext();
     96         final Intent intent = new Intent(context, InstrumentationTestActivity.class);
     97         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
     98 
     99         // Verify when ActivityMonitor.onStartActivity returns non-null, then there is a monitor hit.
    100         final CustomActivityMonitor cam1 = new CustomActivityMonitor(result);
    101         instrumentation.addMonitor(cam1);
    102         context.startActivity(intent);
    103         final Activity activity1 = cam1.waitForActivityWithTimeout(
    104                 CHECK_INTERVAL_FOR_ACTIVITY_LAUNCH_MS * 2);
    105         try {
    106             assertNull("Activity should not have been started", activity1);
    107             assertEquals("There should be 1 monitor hit", 1, cam1.getHits());
    108         } finally {
    109             instrumentation.removeMonitor(cam1);
    110         }
    111 
    112         // Verify when ActivityMonitor.onStartActivity returns null, then activity start is not
    113         // blocked and there is no monitor hit.
    114         final CustomActivityMonitor cam2 = new CustomActivityMonitor(null);
    115         instrumentation.addMonitor(cam2);
    116         Activity activity2 = instrumentation.startActivitySync(intent);
    117         try {
    118             assertNotNull("Activity should not be null", activity2);
    119             assertTrue("Activity returned should be of instance InstrumentationTestActivity",
    120                     activity2 instanceof InstrumentationTestActivity);
    121             assertTrue("InstrumentationTestActivity should have been started",
    122                     ((InstrumentationTestActivity) activity2).isOnCreateCalled());
    123             assertEquals("There should be no monitor hits", 0, cam2.getHits());
    124         } finally {
    125             activity2.finish();
    126             instrumentation.removeMonitor(cam2);
    127         }
    128     }
    129 
    130     /**
    131      * Verifies that when ActivityMonitor.onStartActivity returns non-null, activity start is blocked.
    132      */
    133     public void testActivityMonitor_onStartActivityBlocks() throws Exception {
    134         final Instrumentation instrumentation = getInstrumentation();
    135         final Context context = instrumentation.getTargetContext();
    136 
    137         // Start ActivityMonitorTestActivity
    138         final Intent intent = new Intent(context, ActivityMonitorTestActivity.class)
    139                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    140         ActivityMonitorTestActivity amTestActivity =
    141                 (ActivityMonitorTestActivity) instrumentation.startActivitySync(intent);
    142 
    143         // Initialize and set activity monitor.
    144         final int expectedResultCode = 1111;
    145         final String expectedAction = "matched_using_onStartActivity";
    146         final CustomActivityMonitor cam = new CustomActivityMonitor(
    147                 new ActivityResult(expectedResultCode, new Intent(expectedAction)));
    148         instrumentation.addMonitor(cam);
    149 
    150         // Start InstrumentationTestActivity from ActivityMonitorTestActivity and verify
    151         // it is intercepted using onStartActivity as expected.
    152         try {
    153             final CountDownLatch latch = new CountDownLatch(1);
    154             amTestActivity.setOnActivityResultListener(
    155                     new ActivityMonitorTestActivity.OnActivityResultListener() {
    156                         @Override
    157                         public void onActivityResult(int requestCode, int resultCode, Intent data) {
    158                             assertEquals("Result code is not same as expected",
    159                                     expectedResultCode, resultCode);
    160                             assertNotNull("Data from activity result is null", data);
    161                             assertEquals("Data action is not same as expected",
    162                                     expectedAction, data.getAction());
    163                             latch.countDown();
    164                         }
    165                     });
    166             amTestActivity.startInstrumentationTestActivity(false);
    167             if (!latch.await(TIMEOUT_FOR_ACTIVITY_LAUNCH_MS, TimeUnit.MILLISECONDS)) {
    168                 fail("Timed out waiting for the activity result from "
    169                         + ActivityMonitorTestActivity.class.getName());
    170             }
    171             assertEquals("There should be 1 monitor hit", 1, cam.getHits());
    172         } finally {
    173             amTestActivity.finish();
    174             instrumentation.removeMonitor(cam);
    175         }
    176     }
    177 
    178     /**
    179      * Verifies that when the activity monitor is created using by passing IntentFilter,
    180      * then onStartActivity return value is ignored.
    181      */
    182     public void testActivityMonitor_onStartActivityAndIntentFilter() throws Exception {
    183         final Instrumentation instrumentation = getInstrumentation();
    184         final Context context = instrumentation.getTargetContext();
    185 
    186         // Start ActivityMonitorTestActivity
    187         final Intent intent = new Intent(context, ActivityMonitorTestActivity.class)
    188                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    189         ActivityMonitorTestActivity amTestActivity =
    190                 (ActivityMonitorTestActivity) instrumentation.startActivitySync(intent);
    191 
    192         // Initialize and set activity monitor.
    193         final int expectedResultCode = 1122;
    194         final String expectedAction = "matched_using_intent_filter";
    195         final CustomActivityMonitor cam = new CustomActivityMonitor(
    196                 new IntentFilter(InstrumentationTestActivity.START_INTENT),
    197                 new ActivityResult(expectedResultCode, new Intent(expectedAction)),
    198                 true);
    199         cam.setResultToReturn(new ActivityResult(1111, new Intent("matched_using_onStartActivity")));
    200         instrumentation.addMonitor(cam);
    201 
    202         // Start explicit InstrumentationTestActivity from ActivityMonitorTestActivity and verify
    203         // it is intercepted using the intentFilter as expected.
    204         try {
    205             final CountDownLatch latch = new CountDownLatch(1);
    206             amTestActivity.setOnActivityResultListener(
    207                     new ActivityMonitorTestActivity.OnActivityResultListener() {
    208                         @Override
    209                         public void onActivityResult(int requestCode, int resultCode, Intent data) {
    210                             assertEquals("Result code is not same as expected",
    211                                     expectedResultCode, resultCode);
    212                             assertNotNull("Data from activity result is null", data);
    213                             assertEquals("Data action is not same as expected",
    214                                     expectedAction, data.getAction());
    215                             latch.countDown();
    216                         }
    217                     });
    218             amTestActivity.startInstrumentationTestActivity(false);
    219             if (!latch.await(TIMEOUT_FOR_ACTIVITY_LAUNCH_MS, TimeUnit.MILLISECONDS)) {
    220                 fail("Timed out waiting for the activity result from "
    221                         + ActivityMonitorTestActivity.class.getName());
    222             }
    223             assertEquals("There should be 1 monitor hit", 1, cam.getHits());
    224         } finally {
    225             amTestActivity.finish();
    226             instrumentation.removeMonitor(cam);
    227         }
    228     }
    229 
    230     /**
    231      * Verifies that when the activity monitor is created using by passing activity class,
    232      * then onStartActivity return value is ignored.
    233      */
    234     public void testActivityMonitor_onStartActivityAndActivityClass() throws Exception {
    235         final Instrumentation instrumentation = getInstrumentation();
    236         final Context context = instrumentation.getTargetContext();
    237 
    238         // Start ActivityMonitorTestActivity
    239         final Intent intent = new Intent(context, ActivityMonitorTestActivity.class)
    240                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    241         ActivityMonitorTestActivity amTestActivity =
    242                 (ActivityMonitorTestActivity) instrumentation.startActivitySync(intent);
    243 
    244         // Initialize and set activity monitor.
    245         final int expectedResultCode = 2244;
    246         final String expectedAction = "matched_using_activity_class";
    247         final CustomActivityMonitor cam = new CustomActivityMonitor(
    248                 InstrumentationTestActivity.class.getName(),
    249                 new ActivityResult(expectedResultCode, new Intent(expectedAction)),
    250                 true);
    251         cam.setResultToReturn(new ActivityResult(2222, new Intent("matched_using_onStartActivity")));
    252         instrumentation.addMonitor(cam);
    253 
    254         // Start implicit InstrumentationTestActivity from ActivityMonitorTestActivity and verify
    255         // it is intercepted using the activity class as expected.
    256         try {
    257             final CountDownLatch latch = new CountDownLatch(1);
    258             amTestActivity.setOnActivityResultListener(
    259                     new ActivityMonitorTestActivity.OnActivityResultListener() {
    260                         @Override
    261                         public void onActivityResult(int requestCode, int resultCode, Intent data) {
    262                             assertEquals("Result code is not same as expected",
    263                                     expectedResultCode, resultCode);
    264                             assertNotNull("Data from activity result is null", data);
    265                             assertEquals("Data action is not same as expected",
    266                                     expectedAction, data.getAction());
    267                             latch.countDown();
    268                         }
    269                     });
    270             amTestActivity.startInstrumentationTestActivity(true);
    271             if (!latch.await(TIMEOUT_FOR_ACTIVITY_LAUNCH_MS, TimeUnit.MILLISECONDS)) {
    272                 fail("Timed out waiting for the activity result from "
    273                         + ActivityMonitorTestActivity.class.getName());
    274             }
    275             assertEquals("There should be 1 monitor hit", 1, cam.getHits());
    276         } finally {
    277             amTestActivity.finish();
    278             instrumentation.removeMonitor(cam);
    279         }
    280     }
    281 
    282     private class CustomActivityMonitor extends ActivityMonitor {
    283         private ActivityResult mResultToReturn;
    284 
    285         public CustomActivityMonitor(ActivityResult resultToReturn) {
    286             super();
    287             mResultToReturn = resultToReturn;
    288         }
    289 
    290         public CustomActivityMonitor(IntentFilter intentFilter, ActivityResult result,
    291                 boolean blocked) {
    292             super(intentFilter, result, blocked);
    293         }
    294 
    295         public CustomActivityMonitor(String activityClass, ActivityResult result,
    296                 boolean blocked) {
    297             super(activityClass, result, blocked);
    298         }
    299 
    300         public void setResultToReturn(ActivityResult resultToReturn) {
    301             mResultToReturn = resultToReturn;
    302         }
    303 
    304         @Override
    305         public ActivityResult onStartActivity(Intent intent) {
    306             final boolean implicitInstrumentationTestActivity = intent.getAction() != null &&
    307                     InstrumentationTestActivity.START_INTENT.equals(intent.getAction());
    308             final boolean explicitInstrumentationTestActivity = intent.getComponent() != null &&
    309                     InstrumentationTestActivity.class.getName().equals(
    310                             intent.getComponent().getClassName());
    311             if (implicitInstrumentationTestActivity || explicitInstrumentationTestActivity) {
    312                 return mResultToReturn;
    313             }
    314             return null;
    315         }
    316     }
    317 }
    318