Home | History | Annotate | Download | only in deviceowner
      1 /*
      2  * Copyright (C) 2014 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 package com.android.cts.deviceowner;
     17 
     18 import android.app.ActivityManager;
     19 import android.content.BroadcastReceiver;
     20 import android.content.Context;
     21 import android.content.Intent;
     22 import android.content.IntentFilter;
     23 import android.provider.Settings;
     24 
     25 // This is not a standard test of an android activity (such as
     26 // ActivityInstrumentationTestCase2) as it is attempting to test the actual
     27 // life cycle and how it is affected by lock task, rather than mock intents
     28 // and setup.
     29 public class LockTaskTest extends BaseDeviceOwnerTest {
     30 
     31     private static final String TEST_PACKAGE = "com.google.android.example.somepackage";
     32 
     33     private static final int ACTIVITY_RESUMED_TIMEOUT_MILLIS = 60000;  // 60 seconds
     34     private static final int ACTIVITY_RUNNING_TIMEOUT_MILLIS = 20000;  // 20 seconds
     35 
     36     /**
     37      * The tests below need to keep detailed track of the state of the activity
     38      * that is started and stopped frequently.  To do this it sends a number of
     39      * broadcasts that are caught here and translated into booleans (as well as
     40      * notify some locks in case we are waiting).  There is also an action used
     41      * to specify that the activity has finished handling the current command
     42      * (INTENT_ACTION).
     43      */
     44     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
     45         @Override
     46         public void onReceive(Context context, Intent intent) {
     47             String action = intent.getAction();
     48             if (LockTaskUtilityActivity.CREATE_ACTION.equals(action)) {
     49                 synchronized (mActivityRunningLock) {
     50                     mIsActivityRunning = true;
     51                     mActivityRunningLock.notify();
     52                 }
     53             } else if (LockTaskUtilityActivity.DESTROY_ACTION.equals(action)) {
     54                 synchronized (mActivityRunningLock) {
     55                     mIsActivityRunning = false;
     56                     mActivityRunningLock.notify();
     57                 }
     58             } else if (LockTaskUtilityActivity.RESUME_ACTION.equals(action)) {
     59                 synchronized (mActivityResumedLock) {
     60                     mIsActivityResumed = true;
     61                     mActivityResumedLock.notify();
     62                 }
     63             } else if (LockTaskUtilityActivity.PAUSE_ACTION.equals(action)) {
     64                 synchronized (mActivityResumedLock) {
     65                     mIsActivityResumed = false;
     66                     mActivityResumedLock.notify();
     67                 }
     68             } else if (LockTaskUtilityActivity.INTENT_ACTION.equals(action)) {
     69                 // Notify that intent has been handled.
     70                 synchronized (LockTaskTest.this) {
     71                     mIntentHandled = true;
     72                     LockTaskTest.this.notify();
     73                 }
     74             }
     75         }
     76     };
     77 
     78     private boolean mIsActivityRunning;
     79     private boolean mIsActivityResumed;
     80     private final Object mActivityRunningLock = new Object();
     81     private final Object mActivityResumedLock = new Object();
     82     private Boolean mIntentHandled;
     83 
     84     @Override
     85     protected void setUp() throws Exception {
     86         super.setUp();
     87         IntentFilter filter = new IntentFilter();
     88         filter.addAction(LockTaskUtilityActivity.CREATE_ACTION);
     89         filter.addAction(LockTaskUtilityActivity.DESTROY_ACTION);
     90         filter.addAction(LockTaskUtilityActivity.INTENT_ACTION);
     91         filter.addAction(LockTaskUtilityActivity.RESUME_ACTION);
     92         filter.addAction(LockTaskUtilityActivity.PAUSE_ACTION);
     93         mContext.registerReceiver(mReceiver, filter);
     94     }
     95 
     96     @Override
     97     protected void tearDown() throws Exception {
     98         mContext.unregisterReceiver(mReceiver);
     99         super.tearDown();
    100     }
    101 
    102     public void testSetLockTaskPackages() {
    103         mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { TEST_PACKAGE });
    104         assertTrue(mDevicePolicyManager.isLockTaskPermitted(TEST_PACKAGE));
    105 
    106         mDevicePolicyManager.setLockTaskPackages(getWho(), new String[0]);
    107         assertFalse(mDevicePolicyManager.isLockTaskPermitted(TEST_PACKAGE));
    108     }
    109 
    110     // Start lock task, verify that ActivityManager knows thats what is going on.
    111     public void testStartLockTask() {
    112         mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
    113         startLockTask();
    114         waitForResume();
    115 
    116         // Verify that activity open and activity manager is in lock task.
    117         ActivityManager activityManager = (ActivityManager)
    118                 mContext.getSystemService(Context.ACTIVITY_SERVICE);
    119         assertTrue(activityManager.isInLockTaskMode());
    120         assertTrue(mIsActivityRunning);
    121         assertTrue(mIsActivityResumed);
    122 
    123         stopAndFinish(activityManager);
    124     }
    125 
    126     // Verifies that the act of finishing is blocked by ActivityManager in lock task.
    127     // This results in onDestroy not being called until stopLockTask is called before finish.
    128     public void testCannotFinish() {
    129         mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
    130         startLockTask();
    131 
    132         // If lock task has not exited then the activity shouldn't actually receive onDestroy.
    133         finishAndWait();
    134         ActivityManager activityManager = (ActivityManager)
    135                 mContext.getSystemService(Context.ACTIVITY_SERVICE);
    136         assertTrue(activityManager.isInLockTaskMode());
    137         assertTrue(mIsActivityRunning);
    138 
    139         stopAndFinish(activityManager);
    140     }
    141 
    142     // This test has the UtilityActivity trigger starting another activity (settings)
    143     // this should be permitted as a part of lock task (since it isn't a new task).
    144     // As a result onPause should be called as it goes to a new activity.
    145     public void testStartActivityWithinTask() {
    146         mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
    147         startLockTask();
    148         waitForResume();
    149 
    150         Intent launchIntent = new Intent(Settings.ACTION_SETTINGS);
    151         Intent lockTaskUtility = getLockTaskUtility();
    152         lockTaskUtility.putExtra(LockTaskUtilityActivity.START_ACTIVITY, launchIntent);
    153         mContext.startActivity(lockTaskUtility);
    154 
    155         synchronized (mActivityResumedLock) {
    156             if (mIsActivityResumed) {
    157                 try {
    158                     mActivityResumedLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS);
    159                 } catch (InterruptedException e) {
    160                 }
    161                 assertFalse(mIsActivityResumed);
    162             }
    163         }
    164         stopAndFinish(null);
    165     }
    166 
    167     // This launches an activity that is not part of the current task and therefore
    168     // should be blocked.  This is verified by making sure that the activity does
    169     // not get a call to onPause.
    170     public void testCannotStartActivityOutsideTask() {
    171         mDevicePolicyManager.setLockTaskPackages(getWho(), new String[] { PACKAGE_NAME });
    172         startLockTask();
    173         waitForResume();
    174 
    175         Intent launchIntent = new Intent(Settings.ACTION_SETTINGS);
    176         launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    177         mContext.startActivity(launchIntent);
    178 
    179         synchronized (mActivityResumedLock) {
    180             try {
    181                 mActivityResumedLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS);
    182             } catch (InterruptedException e) {
    183             }
    184             assertTrue(mIsActivityResumed);
    185         }
    186         stopAndFinish(null);
    187     }
    188 
    189     /**
    190      * Call stopLockTask and finish on the LockTaskUtilityActivity.
    191      *
    192      * Verify that the activity is no longer running.
    193      *
    194      * If activityManager is not null then verify that the ActivityManager
    195      * is no longer in lock task mode.
    196      */
    197     private void stopAndFinish(ActivityManager activityManager) {
    198         stopLockTask();
    199         finishAndWait();
    200         if (activityManager != null) {
    201             assertFalse(activityManager.isInLockTaskMode());
    202         }
    203         assertFalse(mIsActivityRunning);
    204     }
    205 
    206     /**
    207      * Call finish on the LockTaskUtilityActivity and wait for
    208      * onDestroy to be called.
    209      */
    210     private void finishAndWait() {
    211         synchronized (mActivityRunningLock) {
    212             finish();
    213             if (mIsActivityRunning) {
    214                 try {
    215                     mActivityRunningLock.wait(ACTIVITY_RUNNING_TIMEOUT_MILLIS);
    216                 } catch (InterruptedException e) {
    217                 }
    218             }
    219         }
    220     }
    221 
    222     /**
    223      * Wait for onPause to be called on the LockTaskUtilityActivity.
    224      */
    225     private void waitForResume() {
    226         // It may take a moment for the resume to come in.
    227         synchronized (mActivityResumedLock) {
    228             if (!mIsActivityResumed) {
    229                 try {
    230                     mActivityResumedLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS);
    231                 } catch (InterruptedException e) {
    232                 }
    233             }
    234         }
    235     }
    236 
    237     /**
    238      * Calls startLockTask on the LockTaskUtilityActivity
    239      */
    240     private void startLockTask() {
    241         Intent intent = getLockTaskUtility();
    242         intent.putExtra(LockTaskUtilityActivity.START_LOCK_TASK, true);
    243         startAndWait(intent);
    244     }
    245 
    246     /**
    247      * Calls stopLockTask on the LockTaskUtilityActivity
    248      */
    249     private void stopLockTask() {
    250         Intent intent = getLockTaskUtility();
    251         intent.putExtra(LockTaskUtilityActivity.STOP_LOCK_TASK, true);
    252         startAndWait(intent);
    253     }
    254 
    255     /**
    256      * Calls finish on the LockTaskUtilityActivity
    257      */
    258     private void finish() {
    259         Intent intent = getLockTaskUtility();
    260         intent.putExtra(LockTaskUtilityActivity.FINISH, true);
    261         startAndWait(intent);
    262     }
    263 
    264     /**
    265      * Sends a command intent to the LockTaskUtilityActivity and waits
    266      * to receive the broadcast back confirming it has finished processing
    267      * the command.
    268      */
    269     private void startAndWait(Intent intent) {
    270         mIntentHandled = false;
    271         synchronized (this) {
    272             mContext.startActivity(intent);
    273             // Give 20 secs to finish.
    274             try {
    275                 wait(ACTIVITY_RUNNING_TIMEOUT_MILLIS);
    276             } catch (InterruptedException e) {
    277             }
    278             assertTrue(mIntentHandled);
    279         }
    280     }
    281 
    282     /**
    283      * Get basic intent that points at the LockTaskUtilityActivity.
    284      *
    285      * This intent includes the flags to make it act as single top.
    286      */
    287     private Intent getLockTaskUtility() {
    288         Intent intent = new Intent();
    289         intent.setClassName(PACKAGE_NAME, LockTaskUtilityActivity.class.getName());
    290         intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
    291         return intent;
    292     }
    293 }
    294