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