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 static junit.framework.Assert.assertEquals;
19 import static junit.framework.Assert.assertFalse;
20 import static junit.framework.Assert.assertTrue;
21 
22 import static org.junit.Assert.assertArrayEquals;
23 
24 import android.app.Activity;
25 import android.app.ActivityManager;
26 import android.app.admin.DevicePolicyManager;
27 import android.content.BroadcastReceiver;
28 import android.content.ComponentName;
29 import android.content.Context;
30 import android.content.Intent;
31 import android.content.IntentFilter;
32 import android.os.Bundle;
33 import android.support.test.InstrumentationRegistry;
34 import android.support.test.runner.AndroidJUnit4;
35 import android.util.Log;
36 
37 import org.junit.After;
38 import org.junit.Before;
39 import org.junit.Test;
40 import org.junit.runner.RunWith;
41 
42 @RunWith(AndroidJUnit4.class)
43 public class LockTaskTest {
44 
45     private static final String TAG = "LockTaskTest";
46 
47     private static final String PACKAGE_NAME = LockTaskTest.class.getPackage().getName();
48     private static final ComponentName ADMIN_COMPONENT =
49             new ComponentName(PACKAGE_NAME, BaseDeviceOwnerTest.BasicAdminReceiver.class.getName());
50     private static final String TEST_PACKAGE = "com.google.android.example.somepackage";
51 
52     private static final String UTILITY_ACTIVITY
53             = "com.android.cts.deviceowner.LockTaskUtilityActivity";
54     private static final String UTILITY_ACTIVITY_IF_WHITELISTED
55             = "com.android.cts.deviceowner.LockTaskUtilityActivityIfWhitelisted";
56 
57     private static final String RECEIVING_ACTIVITY_PACKAGE_NAME
58             = "com.android.cts.intent.receiver";
59     private static final String RECEIVING_ACTIVITY_NAME
60             = "com.android.cts.intent.receiver.IntentReceiverActivity";
61     private static final String ACTION_JUST_CREATE =
62             "com.android.cts.action.JUST_CREATE";
63 
64     private static final int ACTIVITY_RESUMED_TIMEOUT_MILLIS = 20000;  // 20 seconds
65     private static final int ACTIVITY_RUNNING_TIMEOUT_MILLIS = 10000;  // 10 seconds
66     private static final int ACTIVITY_DESTROYED_TIMEOUT_MILLIS = 60000;  // 60 seconds
67     public static final String RECEIVING_ACTIVITY_CREATED_ACTION
68             = "com.android.cts.deviceowner.RECEIVING_ACTIVITY_CREATED_ACTION";
69     /**
70      * The tests below need to keep detailed track of the state of the activity
71      * that is started and stopped frequently.  To do this it sends a number of
72      * broadcasts that are caught here and translated into booleans (as well as
73      * notify some locks in case we are waiting).  There is also an action used
74      * to specify that the activity has finished handling the current command
75      * (INTENT_ACTION).
76      */
77     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
78         @Override
79         public void onReceive(Context context, Intent intent) {
80             String action = intent.getAction();
81             Log.d(TAG, "onReceive: " + action);
82             if (LockTaskUtilityActivity.CREATE_ACTION.equals(action)) {
83                 synchronized (mActivityRunningLock) {
84                     mIsActivityRunning = true;
85                     mActivityRunningLock.notify();
86                 }
87             } else if (LockTaskUtilityActivity.DESTROY_ACTION.equals(action)) {
88                 synchronized (mActivityRunningLock) {
89                     mIsActivityRunning = false;
90                     mActivityRunningLock.notify();
91                 }
92             } else if (LockTaskUtilityActivity.RESUME_ACTION.equals(action)) {
93                 synchronized (mActivityResumedLock) {
94                     mIsActivityResumed = true;
95                     mActivityResumedLock.notify();
96                 }
97             } else if (LockTaskUtilityActivity.PAUSE_ACTION.equals(action)) {
98                 synchronized (mActivityResumedLock) {
99                     mIsActivityResumed = false;
100                     mActivityResumedLock.notify();
101                 }
102             } else if (LockTaskUtilityActivity.INTENT_ACTION.equals(action)) {
103                 // Notify that intent has been handled.
104                 synchronized (LockTaskTest.this) {
105                     mIntentHandled = true;
106                     LockTaskTest.this.notify();
107                 }
108             } else if (RECEIVING_ACTIVITY_CREATED_ACTION.equals(action)) {
109                 synchronized(mReceivingActivityCreatedLock) {
110                     mReceivingActivityWasCreated = true;
111                     mReceivingActivityCreatedLock.notify();
112                 }
113             }
114         }
115     };
116 
117     public static class IntentReceivingActivity extends Activity {
118         @Override
onCreate(Bundle savedInstanceState)119         public void onCreate(Bundle savedInstanceState) {
120             super.onCreate(savedInstanceState);
121             sendBroadcast(new Intent(RECEIVING_ACTIVITY_CREATED_ACTION));
122             finish();
123         }
124     }
125 
126     private volatile boolean mIsActivityRunning;
127     private volatile boolean mIsActivityResumed;
128     private volatile boolean mReceivingActivityWasCreated;
129     private volatile boolean mIntentHandled;
130     private final Object mActivityRunningLock = new Object();
131     private final Object mActivityResumedLock = new Object();
132     private final Object mReceivingActivityCreatedLock = new Object();
133 
134     private Context mContext;
135     private ActivityManager mActivityManager;
136     private DevicePolicyManager mDevicePolicyManager;
137 
138     @Before
setUp()139     public void setUp() {
140         mContext = InstrumentationRegistry.getContext();
141 
142         mDevicePolicyManager = (DevicePolicyManager)
143                 mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
144         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[0]);
145         mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
146         IntentFilter filter = new IntentFilter();
147         filter.addAction(LockTaskUtilityActivity.CREATE_ACTION);
148         filter.addAction(LockTaskUtilityActivity.DESTROY_ACTION);
149         filter.addAction(LockTaskUtilityActivity.INTENT_ACTION);
150         filter.addAction(LockTaskUtilityActivity.RESUME_ACTION);
151         filter.addAction(LockTaskUtilityActivity.PAUSE_ACTION);
152         filter.addAction(RECEIVING_ACTIVITY_CREATED_ACTION);
153         mContext.registerReceiver(mReceiver, filter);
154     }
155 
156     @After
tearDown()157     public void tearDown() {
158         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[0]);
159         mContext.unregisterReceiver(mReceiver);
160     }
161 
162     // Setting and unsetting the lock task packages.
163     @Test
testSetLockTaskPackages()164     public void testSetLockTaskPackages() {
165         final String[] packages = new String[] { TEST_PACKAGE, "some.other.package" };
166         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, packages);
167         assertArrayEquals(packages, mDevicePolicyManager.getLockTaskPackages(ADMIN_COMPONENT));
168         assertTrue(mDevicePolicyManager.isLockTaskPermitted(TEST_PACKAGE));
169 
170         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[0]);
171         assertEquals(0, mDevicePolicyManager.getLockTaskPackages(ADMIN_COMPONENT).length);
172         assertFalse(mDevicePolicyManager.isLockTaskPermitted(TEST_PACKAGE));
173     }
174 
175     // Start lock task, verify that ActivityManager knows thats what is going on.
176     @Test
testStartLockTask()177     public void testStartLockTask() throws Exception {
178         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME });
179         startLockTask(UTILITY_ACTIVITY);
180         waitForResume();
181 
182         // Verify that activity open and activity manager is in lock task.
183         assertLockTaskModeActive();
184         assertTrue(mIsActivityRunning);
185         assertTrue(mIsActivityResumed);
186 
187         stopAndFinish(UTILITY_ACTIVITY);
188     }
189 
190     // Verifies that the act of finishing is blocked by ActivityManager in lock task.
191     // This results in onDestroy not being called until stopLockTask is called before finish.
192     @Test
testCannotFinish()193     public void testCannotFinish() throws Exception {
194         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME });
195         startLockTask(UTILITY_ACTIVITY);
196 
197         // If lock task has not exited then the activity shouldn't actually receive onDestroy.
198         finishAndWait(UTILITY_ACTIVITY);
199         assertLockTaskModeActive();
200         assertTrue(mIsActivityRunning);
201 
202         stopAndFinish(UTILITY_ACTIVITY);
203     }
204 
205     // Verifies that updating the whitelisting during lock task mode finishes the locked task.
206     @Test
testUpdateWhitelisting()207     public void testUpdateWhitelisting() throws Exception {
208         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME });
209         startLockTask(UTILITY_ACTIVITY);
210 
211         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[0]);
212 
213         synchronized (mActivityRunningLock) {
214             mActivityRunningLock.wait(ACTIVITY_DESTROYED_TIMEOUT_MILLIS);
215         }
216 
217         assertLockTaskModeInactive();
218         assertFalse(mIsActivityRunning);
219         assertFalse(mIsActivityResumed);
220     }
221 
222     // This launches an activity that is in the current task.
223     // This should always be permitted as a part of lock task (since it isn't a new task).
224     @Test
testStartActivity_withinTask()225     public void testStartActivity_withinTask() throws Exception {
226         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME });
227         startLockTask(UTILITY_ACTIVITY);
228         waitForResume();
229 
230         mReceivingActivityWasCreated = false;
231         Intent launchIntent = getIntentReceivingActivityIntent(0);
232         Intent lockTaskUtility = getLockTaskUtility(UTILITY_ACTIVITY);
233         lockTaskUtility.putExtra(LockTaskUtilityActivity.START_ACTIVITY, launchIntent);
234         mContext.startActivity(lockTaskUtility);
235 
236         synchronized (mReceivingActivityCreatedLock) {
237             mReceivingActivityCreatedLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS);
238             assertTrue(mReceivingActivityWasCreated);
239         }
240         stopAndFinish(UTILITY_ACTIVITY);
241     }
242 
243     // This launches a whitelisted activity that is not part of the current task.
244     // This should be permitted as a part of lock task.
245     @Test
testStartActivity_outsideTaskWhitelisted()246     public void testStartActivity_outsideTaskWhitelisted() throws Exception {
247         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME,
248                 RECEIVING_ACTIVITY_PACKAGE_NAME });
249         startLockTask(UTILITY_ACTIVITY);
250         waitForResume();
251 
252         mReceivingActivityWasCreated = false;
253         Intent launchIntent = getIntentReceivingActivityIntent(0);
254         launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
255         mContext.startActivity(launchIntent);
256         synchronized (mReceivingActivityCreatedLock) {
257             mReceivingActivityCreatedLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS);
258             assertTrue(mReceivingActivityWasCreated);
259         }
260         stopAndFinish(UTILITY_ACTIVITY);
261     }
262 
263     // This launches a non-whitelisted activity that is not part of the current task.
264     // This should be blocked.
265     @Test
testStartActivity_outsideTaskNonWhitelisted()266     public void testStartActivity_outsideTaskNonWhitelisted() throws Exception {
267         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME });
268         startLockTask(UTILITY_ACTIVITY);
269         waitForResume();
270 
271         Intent launchIntent = getIntentReceivingActivityIntent(Intent.FLAG_ACTIVITY_NEW_TASK);
272         mContext.startActivity(launchIntent);
273         synchronized (mActivityResumedLock) {
274             mActivityResumedLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS);
275             assertFalse(mReceivingActivityWasCreated);
276         }
277         stopAndFinish(UTILITY_ACTIVITY);
278     }
279 
280     // Test the lockTaskMode flag for an activity declaring if_whitelisted.
281     // Whitelist the activity and verify that lock task mode is started.
282     @Test
testManifestArgument_whitelisted()283     public void testManifestArgument_whitelisted() throws Exception {
284         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME });
285         startAndWait(getLockTaskUtility(UTILITY_ACTIVITY_IF_WHITELISTED));
286         waitForResume();
287 
288         assertLockTaskModeActive();
289         assertTrue(mIsActivityRunning);
290         assertTrue(mIsActivityResumed);
291 
292         stopAndFinish(UTILITY_ACTIVITY_IF_WHITELISTED);
293     }
294 
295     // Test the lockTaskMode flag for an activity declaring if_whitelisted.
296     // Don't whitelist the activity and verify that lock task mode is not started.
297     @Test
testManifestArgument_nonWhitelisted()298     public void testManifestArgument_nonWhitelisted() throws Exception {
299         startAndWait(getLockTaskUtility(UTILITY_ACTIVITY_IF_WHITELISTED));
300         waitForResume();
301 
302         assertLockTaskModeInactive();
303         assertTrue(mIsActivityRunning);
304         assertTrue(mIsActivityResumed);
305 
306         stopAndFinish(UTILITY_ACTIVITY_IF_WHITELISTED);
307     }
308 
309     // Test the lockTaskMode flag for an activity declaring if_whitelisted.
310     // An activity locked via manifest argument cannot finish without calling stopLockTask.
311     @Test
testManifestArgument_cannotFinish()312     public void testManifestArgument_cannotFinish() throws Exception {
313         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME });
314         startAndWait(getLockTaskUtility(UTILITY_ACTIVITY_IF_WHITELISTED));
315         waitForResume();
316 
317         // If lock task has not exited then the activity shouldn't actually receive onDestroy.
318         finishAndWait(UTILITY_ACTIVITY_IF_WHITELISTED);
319         assertLockTaskModeActive();
320         assertTrue(mIsActivityRunning);
321 
322         stopAndFinish(UTILITY_ACTIVITY_IF_WHITELISTED);
323     }
324 
325     // Test the lockTaskMode flag for an activity declaring if_whitelisted.
326     // Verifies that updating the whitelisting during lock task mode finishes the locked task.
327     @Test
testManifestArgument_updateWhitelisting()328     public void testManifestArgument_updateWhitelisting() throws Exception {
329         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME });
330         startAndWait(getLockTaskUtility(UTILITY_ACTIVITY_IF_WHITELISTED));
331         waitForResume();
332 
333         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[0]);
334 
335         synchronized (mActivityRunningLock) {
336             mActivityRunningLock.wait(ACTIVITY_DESTROYED_TIMEOUT_MILLIS);
337         }
338 
339         assertLockTaskModeInactive();
340         assertFalse(mIsActivityRunning);
341         assertFalse(mIsActivityResumed);
342     }
343 
344     /**
345      * Checks that lock task mode is active and fails the test if it isn't.
346      */
assertLockTaskModeActive()347     private void assertLockTaskModeActive() {
348         assertTrue(mActivityManager.isInLockTaskMode());
349         assertEquals(ActivityManager.LOCK_TASK_MODE_LOCKED,
350                 mActivityManager.getLockTaskModeState());
351     }
352 
353     /**
354      * Checks that lock task mode is not active and fails the test if it is.
355      */
assertLockTaskModeInactive()356     private void assertLockTaskModeInactive() throws InterruptedException {
357         // Retry 10 times with 200 ms interval.
358         for (int i = 0; i < 10 && mActivityManager.isInLockTaskMode(); i++) {
359             Thread.sleep(200);
360         }
361         assertFalse(mActivityManager.isInLockTaskMode());
362         assertEquals(ActivityManager.LOCK_TASK_MODE_NONE, mActivityManager.getLockTaskModeState());
363     }
364 
365     /**
366      * Call stopLockTask and finish on the LockTaskUtilityActivity.
367      *
368      * Verify that the activity is no longer running.
369      *
370      * If activityManager is not null then verify that the ActivityManager
371      * is no longer in lock task mode.
372      */
stopAndFinish(String className)373     private void stopAndFinish(String className) throws InterruptedException {
374         stopLockTask(className);
375         finishAndWait(className);
376         assertLockTaskModeInactive();
377         assertFalse(mIsActivityRunning);
378     }
379 
380     /**
381      * Call finish on the LockTaskUtilityActivity and wait for
382      * onDestroy to be called.
383      */
finishAndWait(String className)384     private void finishAndWait(String className) throws InterruptedException {
385         synchronized (mActivityRunningLock) {
386             finish(className);
387             if (mIsActivityRunning) {
388                 mActivityRunningLock.wait(ACTIVITY_DESTROYED_TIMEOUT_MILLIS);
389             }
390         }
391     }
392 
393     /**
394      * Wait for onResume to be called on the LockTaskUtilityActivity.
395      */
waitForResume()396     private void waitForResume() throws InterruptedException {
397         // It may take a moment for the resume to come in.
398         synchronized (mActivityResumedLock) {
399             if (!mIsActivityResumed) {
400                 mActivityResumedLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS);
401             }
402         }
403     }
404 
405     /**
406      * Calls startLockTask on the LockTaskUtilityActivity
407      */
startLockTask(String className)408     private void startLockTask(String className) throws InterruptedException {
409         Intent intent = getLockTaskUtility(className);
410         intent.putExtra(LockTaskUtilityActivity.START_LOCK_TASK, true);
411         startAndWait(intent);
412     }
413 
414     /**
415      * Calls stopLockTask on the LockTaskUtilityActivity
416      */
stopLockTask(String className)417     private void stopLockTask(String className) throws InterruptedException {
418         Intent intent = getLockTaskUtility(className);
419         intent.putExtra(LockTaskUtilityActivity.STOP_LOCK_TASK, true);
420         startAndWait(intent);
421     }
422 
423     /**
424      * Calls finish on the LockTaskUtilityActivity
425      */
finish(String className)426     private void finish(String className) throws InterruptedException {
427         Intent intent = getLockTaskUtility(className);
428         intent.putExtra(LockTaskUtilityActivity.FINISH, true);
429         startAndWait(intent);
430     }
431 
432     /**
433      * Sends a command intent to the LockTaskUtilityActivity and waits
434      * to receive the broadcast back confirming it has finished processing
435      * the command.
436      */
startAndWait(Intent intent)437     private void startAndWait(Intent intent) throws InterruptedException {
438         mIntentHandled = false;
439         synchronized (this) {
440             mContext.startActivity(intent);
441             // Give 20 secs to finish.
442             wait(ACTIVITY_RUNNING_TIMEOUT_MILLIS);
443             assertTrue(mIntentHandled);
444         }
445     }
446 
447     /**
448      * Get basic intent that points at the LockTaskUtilityActivity.
449      *
450      * This intent includes the flags to make it act as single top.
451      */
getLockTaskUtility(String className)452     private Intent getLockTaskUtility(String className) {
453         Intent intent = new Intent();
454         intent.setClassName(PACKAGE_NAME, className);
455         intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
456         return intent;
457     }
458 
getIntentReceivingActivityIntent(int flags)459     private Intent getIntentReceivingActivityIntent(int flags) {
460         Intent intent = new Intent();
461         intent.setComponent(
462                 new ComponentName(RECEIVING_ACTIVITY_PACKAGE_NAME, RECEIVING_ACTIVITY_NAME));
463         intent.setAction(ACTION_JUST_CREATE);
464         intent.setFlags(flags);
465         return intent;
466     }
467 }
468