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 android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_GLOBAL_ACTIONS;
19 import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_HOME;
20 import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_KEYGUARD;
21 import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_NONE;
22 import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_NOTIFICATIONS;
23 import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_OVERVIEW;
24 import static android.app.admin.DevicePolicyManager.LOCK_TASK_FEATURE_SYSTEM_INFO;
25 
26 import static junit.framework.Assert.assertEquals;
27 import static junit.framework.Assert.assertFalse;
28 import static junit.framework.Assert.assertTrue;
29 import static org.testng.Assert.assertThrows;
30 
31 import static org.junit.Assert.assertArrayEquals;
32 
33 import android.app.ActivityManager;
34 import android.app.ActivityOptions;
35 import android.app.admin.DevicePolicyManager;
36 import android.content.BroadcastReceiver;
37 import android.content.ComponentName;
38 import android.content.Context;
39 import android.content.Intent;
40 import android.content.IntentFilter;
41 import android.os.Bundle;
42 import android.support.test.InstrumentationRegistry;
43 import android.support.test.runner.AndroidJUnit4;
44 import android.util.Log;
45 
46 import org.junit.After;
47 import org.junit.Before;
48 import org.junit.Test;
49 import org.junit.runner.RunWith;
50 
51 import java.util.concurrent.TimeUnit;
52 
53 @RunWith(AndroidJUnit4.class)
54 public class LockTaskTest {
55 
56     private static final String TAG = "LockTaskTest";
57 
58     private static final String PACKAGE_NAME = LockTaskTest.class.getPackage().getName();
59     private static final ComponentName ADMIN_COMPONENT =
60             new ComponentName(PACKAGE_NAME, BasicAdminReceiver.class.getName());
61     private static final String TEST_PACKAGE = "com.google.android.example.somepackage";
62 
63     private static final String UTILITY_ACTIVITY
64             = "com.android.cts.deviceowner.LockTaskUtilityActivity";
65     private static final String UTILITY_ACTIVITY_IF_WHITELISTED
66             = "com.android.cts.deviceowner.LockTaskUtilityActivityIfWhitelisted";
67 
68     private static final String RECEIVER_ACTIVITY_PACKAGE_NAME =
69             "com.android.cts.intent.receiver";
70     private static final String RECEIVER_ACTIVITY_NAME =
71             "com.android.cts.intent.receiver.IntentReceiverActivity";
72     private static final String ACTION_JUST_CREATE =
73             "com.android.cts.action.JUST_CREATE";
74     private static final String ACTION_CREATE_AND_WAIT =
75             "com.android.cts.action.CREATE_AND_WAIT";
76     private static final String RECEIVER_ACTIVITY_CREATED_ACTION =
77             "com.android.cts.deviceowner.action.RECEIVER_ACTIVITY_CREATED";
78     private static final String RECEIVER_ACTIVITY_DESTROYED_ACTION =
79             "com.android.cts.deviceowner.action.RECEIVER_ACTIVITY_DESTROYED";
80 
81     private static final long ACTIVITY_RESUMED_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(20);
82     private static final long ACTIVITY_RUNNING_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(10);
83     private static final long ACTIVITY_DESTROYED_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(60);
84 
85     /**
86      * The tests below need to keep detailed track of the state of the activity
87      * that is started and stopped frequently.  To do this it sends a number of
88      * broadcasts that are caught here and translated into booleans (as well as
89      * notify some locks in case we are waiting).  There is also an action used
90      * to specify that the activity has finished handling the current command
91      * (INTENT_ACTION).
92      */
93     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
94         @Override
95         public void onReceive(Context context, Intent intent) {
96             String action = intent.getAction();
97             Log.d(TAG, "onReceive: " + action);
98             if (LockTaskUtilityActivity.CREATE_ACTION.equals(action)) {
99                 synchronized (mActivityRunningLock) {
100                     mIsActivityRunning = true;
101                     mActivityRunningLock.notify();
102                 }
103             } else if (LockTaskUtilityActivity.DESTROY_ACTION.equals(action)) {
104                 synchronized (mActivityRunningLock) {
105                     mIsActivityRunning = false;
106                     mActivityRunningLock.notify();
107                 }
108             } else if (LockTaskUtilityActivity.RESUME_ACTION.equals(action)) {
109                 synchronized (mActivityResumedLock) {
110                     mIsActivityResumed = true;
111                     mActivityResumedLock.notify();
112                 }
113             } else if (LockTaskUtilityActivity.PAUSE_ACTION.equals(action)) {
114                 synchronized (mActivityResumedLock) {
115                     mIsActivityResumed = false;
116                     mActivityResumedLock.notify();
117                 }
118             } else if (LockTaskUtilityActivity.INTENT_ACTION.equals(action)) {
119                 // Notify that intent has been handled.
120                 synchronized (LockTaskTest.this) {
121                     mIntentHandled = true;
122                     LockTaskTest.this.notify();
123                 }
124             } else if (RECEIVER_ACTIVITY_CREATED_ACTION.equals(action)) {
125                 synchronized(mReceiverActivityRunningLock) {
126                     mIsReceiverActivityRunning = true;
127                     mReceiverActivityRunningLock.notify();
128                 }
129             } else if (RECEIVER_ACTIVITY_DESTROYED_ACTION.equals(action)) {
130                 synchronized (mReceiverActivityRunningLock) {
131                     mIsReceiverActivityRunning = false;
132                     mReceiverActivityRunningLock.notify();
133                 }
134             }
135         }
136     };
137 
138     private volatile boolean mIsActivityRunning;
139     private volatile boolean mIsActivityResumed;
140     private volatile boolean mIsReceiverActivityRunning;
141     private volatile boolean mIntentHandled;
142     private final Object mActivityRunningLock = new Object();
143     private final Object mActivityResumedLock = new Object();
144     private final Object mReceiverActivityRunningLock = new Object();
145 
146     private Context mContext;
147     private ActivityManager mActivityManager;
148     private DevicePolicyManager mDevicePolicyManager;
149 
150     @Before
setUp()151     public void setUp() {
152         mContext = InstrumentationRegistry.getContext();
153 
154         mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
155         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[0]);
156         mActivityManager = mContext.getSystemService(ActivityManager.class);
157         IntentFilter filter = new IntentFilter();
158         filter.addAction(LockTaskUtilityActivity.CREATE_ACTION);
159         filter.addAction(LockTaskUtilityActivity.DESTROY_ACTION);
160         filter.addAction(LockTaskUtilityActivity.INTENT_ACTION);
161         filter.addAction(LockTaskUtilityActivity.RESUME_ACTION);
162         filter.addAction(LockTaskUtilityActivity.PAUSE_ACTION);
163         filter.addAction(RECEIVER_ACTIVITY_CREATED_ACTION);
164         filter.addAction(RECEIVER_ACTIVITY_DESTROYED_ACTION);
165         mContext.registerReceiver(mReceiver, filter);
166     }
167 
168     @After
tearDown()169     public void tearDown() {
170         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[0]);
171         mContext.unregisterReceiver(mReceiver);
172     }
173 
174     // Setting and unsetting the lock task packages.
175     @Test
testSetLockTaskPackages()176     public void testSetLockTaskPackages() {
177         final String[] packages = new String[] { TEST_PACKAGE, "some.other.package" };
178         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, packages);
179         assertArrayEquals(packages, mDevicePolicyManager.getLockTaskPackages(ADMIN_COMPONENT));
180         assertTrue(mDevicePolicyManager.isLockTaskPermitted(TEST_PACKAGE));
181 
182         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[0]);
183         assertEquals(0, mDevicePolicyManager.getLockTaskPackages(ADMIN_COMPONENT).length);
184         assertFalse(mDevicePolicyManager.isLockTaskPermitted(TEST_PACKAGE));
185     }
186 
187     // Setting and unsetting the lock task features. The actual UI behavior is tested with CTS
188     // verifier.
189     @Test
testSetLockTaskFeatures()190     public void testSetLockTaskFeatures() {
191         final int[] flags = new int[] {
192                 LOCK_TASK_FEATURE_SYSTEM_INFO,
193                 LOCK_TASK_FEATURE_HOME,
194                 LOCK_TASK_FEATURE_NOTIFICATIONS,
195                 LOCK_TASK_FEATURE_OVERVIEW,
196                 LOCK_TASK_FEATURE_GLOBAL_ACTIONS,
197                 LOCK_TASK_FEATURE_KEYGUARD
198         };
199 
200         int cumulative = LOCK_TASK_FEATURE_NONE;
201         for (int flag : flags) {
202             if (flag == LOCK_TASK_FEATURE_OVERVIEW || flag == LOCK_TASK_FEATURE_NOTIFICATIONS) {
203                 // Those flags can only be used in combination with HOME
204                 assertThrows(
205                         IllegalArgumentException.class,
206                         () -> mDevicePolicyManager.setLockTaskFeatures(ADMIN_COMPONENT, flag));
207             } else {
208                 mDevicePolicyManager.setLockTaskFeatures(ADMIN_COMPONENT, flag);
209                 assertEquals(flag, mDevicePolicyManager.getLockTaskFeatures(ADMIN_COMPONENT));
210             }
211 
212             cumulative |= flag;
213             mDevicePolicyManager.setLockTaskFeatures(ADMIN_COMPONENT, cumulative);
214             assertEquals(cumulative, mDevicePolicyManager.getLockTaskFeatures(ADMIN_COMPONENT));
215 
216             mDevicePolicyManager.setLockTaskFeatures(ADMIN_COMPONENT, LOCK_TASK_FEATURE_NONE);
217             assertEquals(LOCK_TASK_FEATURE_NONE,
218                     mDevicePolicyManager.getLockTaskFeatures(ADMIN_COMPONENT));
219         }
220     }
221 
222     // Start lock task, verify that ActivityManager knows thats what is going on.
223     @Test
testStartLockTask()224     public void testStartLockTask() throws Exception {
225         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME });
226         startLockTask(UTILITY_ACTIVITY);
227         waitForResume();
228 
229         // Verify that activity open and activity manager is in lock task.
230         assertLockTaskModeActive();
231         assertTrue(mIsActivityRunning);
232         assertTrue(mIsActivityResumed);
233 
234         stopAndFinish(UTILITY_ACTIVITY);
235     }
236 
237     // Verifies that the act of finishing is blocked by ActivityManager in lock task.
238     // This results in onDestroy not being called until stopLockTask is called before finish.
239     @Test
testCannotFinish()240     public void testCannotFinish() throws Exception {
241         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME });
242         startLockTask(UTILITY_ACTIVITY);
243 
244         // If lock task has not exited then the activity shouldn't actually receive onDestroy.
245         finishAndWait(UTILITY_ACTIVITY);
246         assertLockTaskModeActive();
247         assertTrue(mIsActivityRunning);
248 
249         stopAndFinish(UTILITY_ACTIVITY);
250     }
251 
252     // Verifies that updating the whitelisting during lock task mode finishes the locked task.
253     @Test
testUpdateWhitelisting()254     public void testUpdateWhitelisting() throws Exception {
255         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME });
256         startLockTask(UTILITY_ACTIVITY);
257 
258         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[0]);
259 
260         synchronized (mActivityRunningLock) {
261             mActivityRunningLock.wait(ACTIVITY_DESTROYED_TIMEOUT_MILLIS);
262         }
263 
264         assertLockTaskModeInactive();
265         assertFalse(mIsActivityRunning);
266         assertFalse(mIsActivityResumed);
267     }
268 
269     // Verifies that removing the whitelist authorization immediately finishes the corresponding
270     // locked task. The other locked task(s) should remain locked.
271     @Test
testUpdateWhitelisting_twoTasks()272     public void testUpdateWhitelisting_twoTasks() throws Exception {
273         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME,
274                 RECEIVER_ACTIVITY_PACKAGE_NAME});
275 
276         // Start first locked task
277         startLockTask(UTILITY_ACTIVITY);
278         waitForResume();
279 
280         // Start the other task from the running activity
281         mIsReceiverActivityRunning = false;
282         Intent launchIntent = createReceiverActivityIntent(true /*newTask*/, true /*shouldWait*/);
283         mContext.startActivity(launchIntent);
284         synchronized (mReceiverActivityRunningLock) {
285             mReceiverActivityRunningLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS);
286             assertTrue(mIsReceiverActivityRunning);
287         }
288 
289         // Remove whitelist authorization of the second task
290         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME });
291         synchronized (mReceiverActivityRunningLock) {
292             mReceiverActivityRunningLock.wait(ACTIVITY_DESTROYED_TIMEOUT_MILLIS);
293             assertFalse(mIsReceiverActivityRunning);
294         }
295 
296         assertLockTaskModeActive();
297         assertTrue(mIsActivityRunning);
298         assertTrue(mIsActivityResumed);
299 
300         stopAndFinish(UTILITY_ACTIVITY);
301     }
302 
303     // This launches an activity that is in the current task.
304     // This should always be permitted as a part of lock task (since it isn't a new task).
305     @Test
testStartActivity_withinTask()306     public void testStartActivity_withinTask() throws Exception {
307         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME });
308         startLockTask(UTILITY_ACTIVITY);
309         waitForResume();
310 
311         mIsReceiverActivityRunning = false;
312         Intent launchIntent = createReceiverActivityIntent(false /*newTask*/, false /*shouldWait*/);
313         Intent lockTaskUtility = getLockTaskUtility(UTILITY_ACTIVITY);
314         lockTaskUtility.putExtra(LockTaskUtilityActivity.START_ACTIVITY, launchIntent);
315         mContext.startActivity(lockTaskUtility);
316 
317         synchronized (mReceiverActivityRunningLock) {
318             mReceiverActivityRunningLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS);
319             assertTrue(mIsReceiverActivityRunning);
320         }
321         stopAndFinish(UTILITY_ACTIVITY);
322     }
323 
324     // This launches a whitelisted activity that is not part of the current task.
325     // This should be permitted as a part of lock task.
326     @Test
testStartActivity_outsideTaskWhitelisted()327     public void testStartActivity_outsideTaskWhitelisted() throws Exception {
328         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME,
329                 RECEIVER_ACTIVITY_PACKAGE_NAME});
330         startLockTask(UTILITY_ACTIVITY);
331         waitForResume();
332 
333         mIsReceiverActivityRunning = false;
334         Intent launchIntent = createReceiverActivityIntent(true /*newTask*/, false /*shouldWait*/);
335         mContext.startActivity(launchIntent);
336         synchronized (mReceiverActivityRunningLock) {
337             mReceiverActivityRunningLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS);
338             assertTrue(mIsReceiverActivityRunning);
339         }
340         stopAndFinish(UTILITY_ACTIVITY);
341     }
342 
343     // This launches a non-whitelisted activity that is not part of the current task.
344     // This should be blocked.
345     @Test
testStartActivity_outsideTaskNonWhitelisted()346     public void testStartActivity_outsideTaskNonWhitelisted() throws Exception {
347         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME });
348         startLockTask(UTILITY_ACTIVITY);
349         waitForResume();
350 
351         Intent launchIntent = createReceiverActivityIntent(true /*newTask*/, false /*shouldWait*/);
352         mContext.startActivity(launchIntent);
353         synchronized (mActivityResumedLock) {
354             mActivityResumedLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS);
355             assertFalse(mIsReceiverActivityRunning);
356         }
357         stopAndFinish(UTILITY_ACTIVITY);
358     }
359 
360     // Test the lockTaskMode flag for an activity declaring if_whitelisted.
361     // Whitelist the activity and verify that lock task mode is started.
362     @Test
testManifestArgument_whitelisted()363     public void testManifestArgument_whitelisted() throws Exception {
364         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME });
365         startAndWait(getLockTaskUtility(UTILITY_ACTIVITY_IF_WHITELISTED));
366         waitForResume();
367 
368         assertLockTaskModeActive();
369         assertTrue(mIsActivityRunning);
370         assertTrue(mIsActivityResumed);
371 
372         stopAndFinish(UTILITY_ACTIVITY_IF_WHITELISTED);
373     }
374 
375     // Test the lockTaskMode flag for an activity declaring if_whitelisted.
376     // Don't whitelist the activity and verify that lock task mode is not started.
377     @Test
testManifestArgument_nonWhitelisted()378     public void testManifestArgument_nonWhitelisted() throws Exception {
379         startAndWait(getLockTaskUtility(UTILITY_ACTIVITY_IF_WHITELISTED));
380         waitForResume();
381 
382         assertLockTaskModeInactive();
383         assertTrue(mIsActivityRunning);
384         assertTrue(mIsActivityResumed);
385 
386         stopAndFinish(UTILITY_ACTIVITY_IF_WHITELISTED);
387     }
388 
389     // Test the lockTaskMode flag for an activity declaring if_whitelisted.
390     // An activity locked via manifest argument cannot finish without calling stopLockTask.
391     @Test
testManifestArgument_cannotFinish()392     public void testManifestArgument_cannotFinish() throws Exception {
393         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME });
394         startAndWait(getLockTaskUtility(UTILITY_ACTIVITY_IF_WHITELISTED));
395         waitForResume();
396 
397         // If lock task has not exited then the activity shouldn't actually receive onDestroy.
398         finishAndWait(UTILITY_ACTIVITY_IF_WHITELISTED);
399         assertLockTaskModeActive();
400         assertTrue(mIsActivityRunning);
401 
402         stopAndFinish(UTILITY_ACTIVITY_IF_WHITELISTED);
403     }
404 
405     // Test the lockTaskMode flag for an activity declaring if_whitelisted.
406     // Verifies that updating the whitelisting during lock task mode finishes the locked task.
407     @Test
testManifestArgument_updateWhitelisting()408     public void testManifestArgument_updateWhitelisting() throws Exception {
409         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME });
410         startAndWait(getLockTaskUtility(UTILITY_ACTIVITY_IF_WHITELISTED));
411         waitForResume();
412 
413         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[0]);
414 
415         synchronized (mActivityRunningLock) {
416             mActivityRunningLock.wait(ACTIVITY_DESTROYED_TIMEOUT_MILLIS);
417         }
418 
419         assertLockTaskModeInactive();
420         assertFalse(mIsActivityRunning);
421         assertFalse(mIsActivityResumed);
422     }
423 
424     // Start lock task with ActivityOptions
425     @Test
testActivityOptions_whitelisted()426     public void testActivityOptions_whitelisted() throws Exception {
427         mDevicePolicyManager.setLockTaskPackages(ADMIN_COMPONENT, new String[] { PACKAGE_NAME });
428         startLockTaskWithOptions(UTILITY_ACTIVITY);
429         waitForResume();
430 
431         // Verify that activity open and activity manager is in lock task.
432         assertLockTaskModeActive();
433         assertTrue(mIsActivityRunning);
434         assertTrue(mIsActivityResumed);
435 
436         stopAndFinish(UTILITY_ACTIVITY);
437     }
438 
439     // Starting a non-whitelisted activity with ActivityOptions is not allowed
440     @Test(expected = SecurityException.class)
testActivityOptions_nonWhitelisted()441     public void testActivityOptions_nonWhitelisted() throws Exception {
442         startLockTaskWithOptions(UTILITY_ACTIVITY);
443     }
444 
445     /**
446      * Checks that lock task mode is active and fails the test if it isn't.
447      */
assertLockTaskModeActive()448     private void assertLockTaskModeActive() {
449         assertTrue(mActivityManager.isInLockTaskMode());
450         assertEquals(ActivityManager.LOCK_TASK_MODE_LOCKED,
451                 mActivityManager.getLockTaskModeState());
452     }
453 
454     /**
455      * Checks that lock task mode is not active and fails the test if it is.
456      */
assertLockTaskModeInactive()457     private void assertLockTaskModeInactive() throws InterruptedException {
458         // Retry 10 times with 200 ms interval.
459         for (int i = 0; i < 10 && mActivityManager.isInLockTaskMode(); i++) {
460             Thread.sleep(200);
461         }
462         assertFalse(mActivityManager.isInLockTaskMode());
463         assertEquals(ActivityManager.LOCK_TASK_MODE_NONE, mActivityManager.getLockTaskModeState());
464     }
465 
466     /**
467      * Call stopLockTask and finish on the LockTaskUtilityActivity.
468      *
469      * Verify that the activity is no longer running.
470      *
471      * If activityManager is not null then verify that the ActivityManager
472      * is no longer in lock task mode.
473      */
stopAndFinish(String className)474     private void stopAndFinish(String className) throws InterruptedException {
475         stopLockTask(className);
476         finishAndWait(className);
477         assertLockTaskModeInactive();
478         assertFalse(mIsActivityRunning);
479     }
480 
481     /**
482      * Call finish on the LockTaskUtilityActivity and wait for
483      * onDestroy to be called.
484      */
finishAndWait(String className)485     private void finishAndWait(String className) throws InterruptedException {
486         synchronized (mActivityRunningLock) {
487             finish(className);
488             if (mIsActivityRunning) {
489                 mActivityRunningLock.wait(ACTIVITY_DESTROYED_TIMEOUT_MILLIS);
490             }
491         }
492     }
493 
494     /**
495      * Wait for onResume to be called on the LockTaskUtilityActivity.
496      */
waitForResume()497     private void waitForResume() throws InterruptedException {
498         // It may take a moment for the resume to come in.
499         synchronized (mActivityResumedLock) {
500             if (!mIsActivityResumed) {
501                 mActivityResumedLock.wait(ACTIVITY_RESUMED_TIMEOUT_MILLIS);
502             }
503         }
504     }
505 
506     /**
507      * Calls startLockTask on the LockTaskUtilityActivity
508      */
startLockTask(String className)509     private void startLockTask(String className) throws InterruptedException {
510         Intent intent = getLockTaskUtility(className);
511         intent.putExtra(LockTaskUtilityActivity.START_LOCK_TASK, true);
512         startAndWait(intent);
513     }
514 
515     /**
516      * Starts LockTaskUtilityActivity with {@link ActivityOptions#setLockTaskEnabled(boolean)}
517      */
startLockTaskWithOptions(String className)518     private void startLockTaskWithOptions(String className) throws InterruptedException {
519         Intent intent = getLockTaskUtility(className);
520         Bundle options = ActivityOptions.makeBasic().setLockTaskEnabled(true).toBundle();
521         startAndWait(intent, options);
522     }
523 
524     /**
525      * Calls stopLockTask on the LockTaskUtilityActivity
526      */
stopLockTask(String className)527     private void stopLockTask(String className) throws InterruptedException {
528         Intent intent = getLockTaskUtility(className);
529         intent.putExtra(LockTaskUtilityActivity.STOP_LOCK_TASK, true);
530         startAndWait(intent);
531     }
532 
533     /**
534      * Calls finish on the LockTaskUtilityActivity
535      */
finish(String className)536     private void finish(String className) throws InterruptedException {
537         Intent intent = getLockTaskUtility(className);
538         intent.putExtra(LockTaskUtilityActivity.FINISH, true);
539         startAndWait(intent);
540     }
541 
542     /**
543      * Sends a command intent to the LockTaskUtilityActivity and waits
544      * to receive the broadcast back confirming it has finished processing
545      * the command.
546      */
startAndWait(Intent intent)547     private void startAndWait(Intent intent) throws InterruptedException {
548         startAndWait(intent, null);
549     }
550 
551     /**
552      * Same as {@link #startAndWait(Intent)}, but with additional {@link ActivityOptions}.
553      */
startAndWait(Intent intent, Bundle options)554     private void startAndWait(Intent intent, Bundle options) throws InterruptedException {
555         mIntentHandled = false;
556         synchronized (this) {
557             mContext.startActivity(intent, options);
558             // Give 20 secs to finish.
559             wait(ACTIVITY_RUNNING_TIMEOUT_MILLIS);
560             assertTrue(mIntentHandled);
561         }
562     }
563 
564     /**
565      * Get basic intent that points at the LockTaskUtilityActivity.
566      *
567      * This intent includes the flags to make it act as single top.
568      */
getLockTaskUtility(String className)569     private Intent getLockTaskUtility(String className) {
570         Intent intent = new Intent();
571         intent.setClassName(PACKAGE_NAME, className);
572         intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
573         return intent;
574     }
575 
576     /** Create an intent to launch {@link #RECEIVER_ACTIVITY_NAME}. */
createReceiverActivityIntent(boolean newTask, boolean shouldWait)577     private Intent createReceiverActivityIntent(boolean newTask, boolean shouldWait) {
578         final Intent intent = new Intent();
579         intent.setComponent(
580                 new ComponentName(RECEIVER_ACTIVITY_PACKAGE_NAME, RECEIVER_ACTIVITY_NAME));
581         intent.setAction(shouldWait ? ACTION_CREATE_AND_WAIT : ACTION_JUST_CREATE);
582         intent.setFlags(newTask ? Intent.FLAG_ACTIVITY_NEW_TASK : 0);
583         return intent;
584     }
585 }
586