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