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