1 /*
2  * Copyright (C) 2017 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 
17 package android.app.cts;
18 
19 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA;
20 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION;
21 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE;
22 import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE;
23 import static android.app.ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK;
24 import static android.app.ActivityManager.PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK;
25 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED;
26 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
27 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
28 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
29 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
30 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
31 import static android.app.cts.ActivityManagerFgsBgStartTest.toggleBgFgsTypeStartPermissionEnforcement;
32 import static android.app.stubs.LocalForegroundService.ACTION_START_FGS_RESULT;
33 import static android.app.stubs.LocalForegroundServiceSticky.ACTION_RESTART_FGS_STICKY_RESULT;
34 import static android.content.ContentResolver.SCHEME_CONTENT;
35 
36 import static com.android.compatibility.common.util.SystemUtil.runShellCommand;
37 
38 import static junit.framework.Assert.assertEquals;
39 import static junit.framework.Assert.assertTrue;
40 import static junit.framework.Assert.fail;
41 
42 import android.accessibilityservice.AccessibilityService;
43 import android.app.Activity;
44 import android.app.ActivityManager;
45 import android.app.ActivityOptions;
46 import android.app.AppOpsManager;
47 import android.app.Instrumentation;
48 import android.app.Service;
49 import android.app.cts.android.app.cts.tools.ServiceConnectionHandler;
50 import android.app.cts.android.app.cts.tools.ServiceProcessController;
51 import android.app.cts.android.app.cts.tools.SyncOrderedBroadcast;
52 import android.app.cts.android.app.cts.tools.UidImportanceListener;
53 import android.app.cts.android.app.cts.tools.WaitForBroadcast;
54 import android.app.cts.android.app.cts.tools.WatchUidRunner;
55 import android.app.stubs.CommandReceiver;
56 import android.app.stubs.LocalForegroundServiceLocation;
57 import android.app.stubs.LocalForegroundServiceSticky;
58 import android.app.stubs.ScreenOnActivity;
59 import android.app.stubs.TestProvider;
60 import android.content.BroadcastReceiver;
61 import android.content.ComponentName;
62 import android.content.Context;
63 import android.content.Intent;
64 import android.content.pm.ApplicationInfo;
65 import android.content.pm.PackageManager;
66 import android.content.pm.ServiceInfo;
67 import android.net.Uri;
68 import android.os.Build;
69 import android.os.Bundle;
70 import android.os.IBinder;
71 import android.os.Parcel;
72 import android.os.RemoteException;
73 import android.os.SystemClock;
74 import android.os.UserHandle;
75 import android.permission.cts.PermissionUtils;
76 import android.platform.test.annotations.Presubmit;
77 import android.server.wm.WindowManagerStateHelper;
78 import android.util.Log;
79 
80 import androidx.test.ext.junit.runners.AndroidJUnit4;
81 import androidx.test.platform.app.InstrumentationRegistry;
82 import androidx.test.uiautomator.BySelector;
83 import androidx.test.uiautomator.UiDevice;
84 import androidx.test.uiautomator.UiSelector;
85 
86 import com.android.compatibility.common.util.AmMonitor;
87 import com.android.compatibility.common.util.SystemUtil;
88 
89 import org.junit.After;
90 import org.junit.Before;
91 import org.junit.Test;
92 import org.junit.runner.RunWith;
93 
94 import java.util.ArrayList;
95 import java.util.Arrays;
96 import java.util.List;
97 import java.util.concurrent.CountDownLatch;
98 import java.util.concurrent.TimeUnit;
99 import java.util.function.BiConsumer;
100 
101 @RunWith(AndroidJUnit4.class)
102 @Presubmit
103 public class ActivityManagerProcessStateTest {
104     private static final String TAG = ActivityManagerProcessStateTest.class.getName();
105 
106     private static final String STUB_PACKAGE_NAME = "android.app.stubs";
107     private static final String PACKAGE_NAME_APP1 = "com.android.app1";
108     private static final String PACKAGE_NAME_APP2 = "com.android.app2";
109     private static final String PACKAGE_NAME_APP3 = "com.android.app3";
110     private static final String PACKAGE_NAME_PROVIDER_APP = "com.android.app.cts.provider";
111 
112     private static final String[] PACKAGE_NAMES = {
113             PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, PACKAGE_NAME_APP3
114     };
115 
116     private static final int WAIT_TIME = 10000;
117     private static final int WAITFOR_MSEC = 10000;
118     private static final int WAITFOR_ORDERED_BROADCAST_DRAINED = 60000;
119     // A secondary test activity from another APK.
120     static final String SIMPLE_PACKAGE_NAME = "com.android.cts.launcherapps.simpleapp";
121     static final String SIMPLE_SERVICE = ".SimpleService";
122     static final String SIMPLE_SERVICE2 = ".SimpleService2";
123     static final String SIMPLE_SERVICE3 = ".SimpleService3";
124     static final String SIMPLE_RECEIVER_START_SERVICE = ".SimpleReceiverStartService";
125     static final String SIMPLE_ACTIVITY_START_SERVICE = ".SimpleActivityStartService";
126     static final String SIMPLE_ACTIVITY_START_FG_SERVICE = ".SimpleActivityStartFgService";
127     public static String ACTION_SIMPLE_ACTIVITY_START_SERVICE_RESULT =
128             "com.android.cts.launcherapps.simpleapp.SimpleActivityStartService.RESULT";
129     static final String ACTION_SIMPLE_ACTIVITY_START_FG =
130             "com.android.cts.launcherapps.simpleapp.SimpleActivityStartFgService.START_THEN_FG";
131     public static String ACTION_SIMPLE_ACTIVITY_START_FG_SERVICE_RESULT =
132             "com.android.cts.launcherapps.simpleapp.SimpleActivityStartFgService.NOW_FOREGROUND";
133     public static String ACTION_FINISH_EVERYTHING =
134             "com.android.cts.launcherapps.simpleapp.SimpleActivityStartFgService.FINISH_ALL";
135 
136     // APKs for testing heavy weight app interactions.
137     static final String CANT_SAVE_STATE_1_PACKAGE_NAME = "com.android.test.cantsavestate1";
138     static final String CANT_SAVE_STATE_2_PACKAGE_NAME = "com.android.test.cantsavestate2";
139 
140     // Actions
141     static final String ACTION_START_FOREGROUND = "com.android.test.action.START_FOREGROUND";
142     static final String ACTION_STOP_FOREGROUND = "com.android.test.action.STOP_FOREGROUND";
143     static final String ACTION_START_THEN_FG = "com.android.test.action.START_THEN_FG";
144     static final String ACTION_STOP_SERVICE = "com.android.test.action.STOP";
145     static final String ACTION_FINISH = "com.android.test.action.FINISH";
146 
147     private static final int TEMP_WHITELIST_DURATION_MS = 2000;
148 
149     private Context mContext;
150     private Context mTargetContext;
151     private Instrumentation mInstrumentation;
152     private Intent mServiceIntent;
153     private Intent mServiceStartForegroundIntent;
154     private Intent mServiceStopForegroundIntent;
155     private Intent mService2Intent;
156     private Intent mService3Intent;
157     private Intent mServiceStartForeground3Intent;
158     private Intent mMainProcess[];
159     private Intent mAllProcesses[];
160 
161     private int mAppCount;
162     private ApplicationInfo[] mAppInfo;
163     private WatchUidRunner[] mWatchers;
164 
165     private static final int PROCESS_CAPABILITY_ALL = PROCESS_CAPABILITY_FOREGROUND_LOCATION
166             | PROCESS_CAPABILITY_FOREGROUND_CAMERA
167             | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE
168             | PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK
169             | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK;
170 
171     @Before
setUp()172     public void setUp() throws Exception {
173         mInstrumentation = InstrumentationRegistry.getInstrumentation();
174         mContext = mInstrumentation.getContext();
175         mTargetContext = mInstrumentation.getTargetContext();
176         mServiceIntent = new Intent();
177         mServiceIntent.setClassName(SIMPLE_PACKAGE_NAME, SIMPLE_PACKAGE_NAME + SIMPLE_SERVICE);
178         mServiceStartForegroundIntent = new Intent(mServiceIntent);
179         mServiceStartForegroundIntent.setAction(ACTION_START_FOREGROUND);
180         mServiceStopForegroundIntent = new Intent(mServiceIntent);
181         mServiceStopForegroundIntent.setAction(ACTION_STOP_FOREGROUND);
182         mService2Intent = new Intent()
183                 .setClassName(SIMPLE_PACKAGE_NAME, SIMPLE_PACKAGE_NAME + SIMPLE_SERVICE2);
184         mService3Intent = new Intent()
185                 .setClassName(SIMPLE_PACKAGE_NAME, SIMPLE_PACKAGE_NAME + SIMPLE_SERVICE3);
186         mMainProcess = new Intent[1];
187         mMainProcess[0] = mServiceIntent;
188         mAllProcesses = new Intent[2];
189         mAllProcesses[0] = mServiceIntent;
190         mAllProcesses[1] = mService2Intent;
191         mContext.stopService(mServiceIntent);
192         mContext.stopService(mService2Intent);
193         mContext.stopService(mService3Intent);
194         CtsAppTestUtils.turnScreenOn(mInstrumentation, mContext);
195         removeTestAppFromWhitelists();
196         mAppCount = 0;
197         drainOrderedBroadcastQueue();
198         // Make sure we are in Home screen before starting the test
199         mInstrumentation.getUiAutomation().performGlobalAction(
200                 AccessibilityService.GLOBAL_ACTION_HOME);
201         // Stop all the packages to avoid residual impact
202         final ActivityManager am = mContext.getSystemService(ActivityManager.class);
203         for (int i = 0; i < PACKAGE_NAMES.length; i++) {
204             final String pkgName = PACKAGE_NAMES[i];
205             SystemUtil.runWithShellPermissionIdentity(() -> {
206                 am.forceStopPackage(pkgName);
207             });
208         }
209 
210         // Override the memory pressure level, force it staying at normal.
211         runShellCommand(mInstrumentation, "am memory-factor set NORMAL");
212     }
213 
214     @After
tearDown()215     public void tearDown() throws Exception {
216         // Stop all the packages
217         final List<String> allPackageNames = new ArrayList<>();
218         allPackageNames.addAll(Arrays.asList(PACKAGE_NAMES));
219         allPackageNames.add(SIMPLE_PACKAGE_NAME);
220         allPackageNames.add(CANT_SAVE_STATE_1_PACKAGE_NAME);
221         allPackageNames.add(CANT_SAVE_STATE_2_PACKAGE_NAME);
222         final ActivityManager am = mContext.getSystemService(ActivityManager.class);
223         for (final String pkgName : allPackageNames) {
224             SystemUtil.runWithShellPermissionIdentity(() -> {
225                 am.forceStopPackage(pkgName);
226             });
227         }
228 
229         // Reset the memory pressure override
230         runShellCommand(mInstrumentation, "am memory-factor reset");
231     }
232 
233     /**
234      * Drain the ordered broadcast queue, it'll be useful when the test runs in secondary user
235      * which is just created prior to the testing, the ordered broadcast queue could be clogged.
236      */
drainOrderedBroadcastQueue()237     private void drainOrderedBroadcastQueue() throws Exception {
238         final CountDownLatch latch = new CountDownLatch(1);
239         final BroadcastReceiver receiver = new BroadcastReceiver() {
240             @Override
241             public void onReceive(Context context, Intent intent) {
242                 latch.countDown();
243             }
244         };
245         CommandReceiver.sendCommandWithResultReceiver(mContext, CommandReceiver.COMMAND_EMPTY,
246                 STUB_PACKAGE_NAME, STUB_PACKAGE_NAME, 0, null, receiver);
247         latch.await(WAITFOR_ORDERED_BROADCAST_DRAINED, TimeUnit.MILLISECONDS);
248         Log.i(TAG, "Ordered broadcast queue drained");
249     }
250 
251     /**
252      * Set up count app info objects and WatchUidRunners.
253      */
setupWatchers(int count)254     private void setupWatchers(int count) throws Exception {
255         mAppCount = count;
256         mAppInfo = new ApplicationInfo[count];
257         mWatchers = new WatchUidRunner[count];
258         for (int i = 0; i < count; i++) {
259             mAppInfo[i] = mContext.getPackageManager().getApplicationInfo(
260                     PACKAGE_NAMES[i], 0);
261             mWatchers[i] = new WatchUidRunner(mInstrumentation, mAppInfo[i].uid,
262                     WAITFOR_MSEC, PROCESS_CAPABILITY_ALL);
263         }
264     }
265 
266     /**
267      * Finish all started WatchUidRunners.
268      */
shutdownWatchers()269     private void shutdownWatchers() throws Exception {
270         for (int i = 0; i < mAppCount; i++) {
271             mWatchers[i].finish();
272         }
273     }
274 
removeTestAppFromWhitelists()275     private void removeTestAppFromWhitelists() throws Exception {
276         CtsAppTestUtils.executeShellCmd(mInstrumentation,
277                 "cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME);
278         CtsAppTestUtils.executeShellCmd(mInstrumentation,
279                 "cmd deviceidle tempwhitelist -r " + SIMPLE_PACKAGE_NAME);
280     }
281 
waitForAppFocus(String waitForApp, long waitTime)282     private void waitForAppFocus(String waitForApp, long waitTime) {
283         final WindowManagerStateHelper wms = new WindowManagerStateHelper();
284         long waitUntil = SystemClock.elapsedRealtime() + waitTime;
285         while (true) {
286             wms.computeState();
287             String appName = wms.getFocusedApp();
288             if (appName != null) {
289                 ComponentName comp = ComponentName.unflattenFromString(appName);
290                 if (waitForApp.equals(comp.getPackageName())) {
291                     break;
292                 }
293             }
294             if (SystemClock.elapsedRealtime() > waitUntil) {
295                 throw new IllegalStateException("Timed out waiting for focus on app "
296                         + waitForApp + ", last was " + appName);
297             }
298             Log.i(TAG, "Waiting for app focus, current: " + appName);
299             try {
300                 Thread.sleep(100);
301             } catch (InterruptedException e) {
302             }
303         }
304     }
305 
startActivity(Context context, final Intent intent)306     private void startActivity(Context context, final Intent intent) {
307         ActivityOptions activityOptions = ActivityOptions.makeBasic();
308         activityOptions.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
309         context.startActivity(intent, activityOptions.toBundle());
310     }
311 
startAndWaitForHeavyWeightSwitcherActivity(final Intent intent)312     private void startAndWaitForHeavyWeightSwitcherActivity(final Intent intent)  {
313         startActivity(mTargetContext, intent);
314         // Assume there was another CANT_SAVE_STATE app, so it will redirect to the switch activity.
315         new WindowManagerStateHelper().waitAndAssertWindowSurfaceShown(
316                 "android/com.android.internal.app.HeavyWeightSwitcherActivity", true);
317         // Wait for the transition animation to complete.
318         mInstrumentation.getUiAutomation().syncInputTransactions();
319     }
320 
maybeClick(UiDevice device, UiSelector sel)321     private void maybeClick(UiDevice device, UiSelector sel) {
322         try {
323             device.findObject(sel).click();
324         } catch (Throwable ignored) {
325         }
326     }
327 
maybeClick(UiDevice device, BySelector sel)328     private void maybeClick(UiDevice device, BySelector sel) {
329         try {
330             device.findObject(sel).click();
331         } catch (Throwable ignored) {
332         }
333     }
334 
335     /**
336      * Test basic state changes as processes go up and down due to services running in them.
337      */
338     @Test
testUidImportanceListener()339     public void testUidImportanceListener() throws Exception {
340         final Parcel data = Parcel.obtain();
341         ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext, mServiceIntent,
342                 WAIT_TIME);
343         ServiceConnectionHandler conn2 = new ServiceConnectionHandler(mContext, mService2Intent,
344                 WAIT_TIME);
345 
346         ActivityManager am = mContext.getSystemService(ActivityManager.class);
347 
348         ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo(
349                 SIMPLE_PACKAGE_NAME, 0);
350         UidImportanceListener uidForegroundListener = new UidImportanceListener(mContext,
351                 appInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE, WAIT_TIME);
352 
353         PermissionUtils.revokePermission(
354                 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS);
355         boolean gotException = false;
356         try {
357             uidForegroundListener.register();
358         } catch (SecurityException e) {
359             gotException = true;
360         }
361         assertTrue("Expected SecurityException thrown", gotException);
362 
363         PermissionUtils.grantPermission(
364                 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS);
365         /*
366         Log.d("XXXX", "Invoke: " + cmd);
367         Log.d("XXXX", "Result: " + result);
368         Log.d("XXXX", SystemUtil.runShellCommand(mInstrumentation, "dumpsys package "
369                 + STUB_PACKAGE_NAME));
370         */
371         uidForegroundListener.register();
372 
373         UidImportanceListener uidGoneListener = new UidImportanceListener(mContext,
374                 appInfo.uid, IMPORTANCE_CACHED, WAIT_TIME);
375         uidGoneListener.register();
376 
377         WatchUidRunner uidWatcher = new WatchUidRunner(mInstrumentation, appInfo.uid,
378                 WAIT_TIME);
379 
380         try {
381             // First kill the processes to start out in a stable state.
382             conn.bind();
383             conn2.bind();
384             IBinder service1 = conn.getServiceIBinder();
385             IBinder service2 = conn2.getServiceIBinder();
386             conn.unbind();
387             conn2.unbind();
388             try {
389                 service1.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0);
390             } catch (RemoteException e) {
391             }
392             try {
393                 service2.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0);
394             } catch (RemoteException e) {
395             }
396             service1 = service2 = null;
397 
398             // Wait for uid's processes to go away.
399             uidGoneListener.waitForValue(IMPORTANCE_GONE, IMPORTANCE_GONE);
400             assertEquals(IMPORTANCE_GONE, am.getPackageImportance(SIMPLE_PACKAGE_NAME));
401 
402             // And wait for the uid report to be gone.
403             uidWatcher.waitFor(WatchUidRunner.CMD_GONE, null);
404 
405             // Now bind and see if we get told about the uid coming in to the foreground.
406             conn.bind();
407             uidForegroundListener.waitForValue(IMPORTANCE_FOREGROUND, IMPORTANCE_VISIBLE);
408             assertEquals(IMPORTANCE_FOREGROUND_SERVICE,
409                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
410 
411             // Also make sure the uid state reports are as expected.  Wait for active because
412             // there may be some intermediate states as the process comes up.
413             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
414             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
415             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
416 
417             // Pull out the service IBinder for a kludy hack...
418             IBinder service = conn.getServiceIBinder();
419 
420             // Now unbind and see if we get told about it going to the background.
421             conn.unbind();
422             uidForegroundListener.waitForValue(IMPORTANCE_CACHED, IMPORTANCE_CACHED);
423             assertEquals(IMPORTANCE_CACHED, am.getPackageImportance(SIMPLE_PACKAGE_NAME));
424 
425             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null);
426             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
427 
428             // Now kill the process and see if we are told about it being gone.
429             try {
430                 service.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0);
431             } catch (RemoteException e) {
432                 // It is okay if it is already gone for some reason.
433             }
434 
435             uidGoneListener.waitForValue(IMPORTANCE_GONE, IMPORTANCE_GONE);
436             assertEquals(IMPORTANCE_GONE, am.getPackageImportance(SIMPLE_PACKAGE_NAME));
437 
438             uidWatcher.expect(WatchUidRunner.CMD_IDLE, null);
439             uidWatcher.expect(WatchUidRunner.CMD_GONE, null);
440 
441             // Now we are going to try different combinations of binding to two processes to
442             // see if they are correctly combined together for the app.
443 
444             // Bring up both services.
445             conn.bind();
446             conn2.bind();
447             uidForegroundListener.waitForValue(IMPORTANCE_FOREGROUND, IMPORTANCE_VISIBLE);
448             assertEquals(IMPORTANCE_FOREGROUND_SERVICE,
449                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
450 
451             // Also make sure the uid state reports are as expected.
452             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
453             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
454             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
455 
456             // Bring down one service, app state should remain foreground.
457             conn2.unbind();
458             assertEquals(IMPORTANCE_FOREGROUND_SERVICE,
459                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
460 
461             // Bring down other service, app state should now be cached.  (If the processes both
462             // actually get killed immediately, this is also not a correctly behaving system.)
463             conn.unbind();
464             uidGoneListener.waitForValue(IMPORTANCE_CACHED, IMPORTANCE_CACHED);
465             assertEquals(IMPORTANCE_CACHED,
466                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
467 
468             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null);
469             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
470 
471             // Bring up one service, this should be sufficient to become foreground.
472             conn2.bind();
473             uidForegroundListener.waitForValue(IMPORTANCE_FOREGROUND, IMPORTANCE_VISIBLE);
474             assertEquals(IMPORTANCE_FOREGROUND_SERVICE,
475                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
476 
477             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
478             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
479 
480             // Bring up other service, should remain foreground.
481             conn.bind();
482             assertEquals(IMPORTANCE_FOREGROUND_SERVICE,
483                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
484 
485             // Bring down one service, should remain foreground.
486             conn.unbind();
487             assertEquals(IMPORTANCE_FOREGROUND_SERVICE,
488                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
489 
490             // And bringing down other service should put us back to cached.
491             conn2.unbind();
492             uidGoneListener.waitForValue(IMPORTANCE_CACHED,
493                     IMPORTANCE_CACHED);
494             assertEquals(IMPORTANCE_CACHED,
495                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
496 
497             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null);
498             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
499         } finally {
500             data.recycle();
501             uidWatcher.finish();
502             uidForegroundListener.unregister();
503             uidGoneListener.unregister();
504         }
505     }
506 
507     /**
508      * Test that background check correctly prevents idle services from running but allows
509      * whitelisted apps to bypass the check.
510      */
511     @Test
testBackgroundCheckService()512     public void testBackgroundCheckService() throws Exception {
513         final Parcel data = Parcel.obtain();
514         Intent serviceIntent = new Intent();
515         serviceIntent.setClassName(SIMPLE_PACKAGE_NAME,
516                 SIMPLE_PACKAGE_NAME + SIMPLE_SERVICE);
517         ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext, serviceIntent,
518                 WAIT_TIME);
519 
520         ActivityManager am = mContext.getSystemService(ActivityManager.class);
521 
522         PermissionUtils.grantPermission(
523                 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS);
524         /*
525         Log.d("XXXX", "Invoke: " + cmd);
526         Log.d("XXXX", "Result: " + result);
527         Log.d("XXXX", SystemUtil.runShellCommand(mInstrumentation, "dumpsys package "
528                 + STUB_PACKAGE_NAME));
529         */
530 
531         ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo(
532                 SIMPLE_PACKAGE_NAME, 0);
533 
534         UidImportanceListener uidForegroundListener = new UidImportanceListener(mContext,
535                 appInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE, WAIT_TIME);
536         uidForegroundListener.register();
537         UidImportanceListener uidGoneListener = new UidImportanceListener(mContext,
538                 appInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY, WAIT_TIME);
539         uidGoneListener.register();
540 
541         WatchUidRunner uidWatcher = new WatchUidRunner(mInstrumentation, appInfo.uid,
542                 WAIT_TIME);
543 
544         final int userId = UserHandle.getUserId(appInfo.uid);
545 
546         // First kill the process to start out in a stable state.
547         mContext.stopService(serviceIntent);
548         conn.bind();
549         IBinder service = conn.getServiceIBinder();
550         conn.unbind();
551         try {
552             service.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0);
553         } catch (RemoteException e) {
554         }
555         service = null;
556 
557         // Wait for uid's process to go away.
558         uidGoneListener.waitForValue(IMPORTANCE_GONE, IMPORTANCE_GONE);
559         assertEquals(IMPORTANCE_GONE,
560                 am.getPackageImportance(SIMPLE_PACKAGE_NAME));
561 
562         // And wait for the uid report to be gone.
563         uidWatcher.waitFor(WatchUidRunner.CMD_GONE, null);
564 
565         String cmd = "appops set --user " + userId + " "
566                 + SIMPLE_PACKAGE_NAME + " RUN_IN_BACKGROUND deny";
567         String result = SystemUtil.runShellCommand(mInstrumentation, cmd);
568 
569         // This is a side-effect of the app op command.
570         uidWatcher.expect(WatchUidRunner.CMD_IDLE, null);
571         uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "NONE");
572 
573         // We don't want to wait for the uid to actually go idle, we can force it now.
574         cmd = "am make-uid-idle --user " + userId + " " + SIMPLE_PACKAGE_NAME;
575         result = SystemUtil.runShellCommand(mInstrumentation, cmd);
576 
577         // Make sure app is not yet on whitelist
578         cmd = "cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME;
579         result = SystemUtil.runShellCommand(mInstrumentation, cmd);
580 
581         // We will use this to monitor when the service is running.
582         conn.startMonitoring();
583 
584         try {
585             // Try starting the service.  Should fail!
586             boolean failed = false;
587             try {
588                 mContext.startService(serviceIntent);
589             } catch (IllegalStateException e) {
590                 failed = true;
591             }
592             if (!failed) {
593                 fail("Service was allowed to start while in the background");
594             }
595 
596             // Put app on temporary whitelist to see if this allows the service start.
597             cmd = String.format("cmd deviceidle tempwhitelist -u %d -d %d %s",
598                     userId, TEMP_WHITELIST_DURATION_MS, SIMPLE_PACKAGE_NAME);
599             result = SystemUtil.runShellCommand(mInstrumentation, cmd);
600 
601             // Try starting the service now that the app is whitelisted...  should work!
602             mContext.startService(serviceIntent);
603             conn.waitForConnect();
604 
605             // Also make sure the uid state reports are as expected.
606             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
607             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
608             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
609 
610             // Good, now stop the service and give enough time to get off the temp whitelist.
611             mContext.stopService(serviceIntent);
612             conn.waitForDisconnect();
613 
614             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
615             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
616 
617             CtsAppTestUtils.executeShellCmd(mInstrumentation,
618                     "cmd deviceidle tempwhitelist -u " + userId + " -r " + SIMPLE_PACKAGE_NAME);
619 
620             // Going off the temp whitelist causes a spurious proc state report...  that's
621             // not ideal, but okay.
622             // uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
623 
624             // We don't want to wait for the uid to actually go idle, we can force it now.
625             cmd = "am make-uid-idle --user " + userId + " " + SIMPLE_PACKAGE_NAME;
626             result = SystemUtil.runShellCommand(mInstrumentation, cmd);
627 
628             uidWatcher.expect(WatchUidRunner.CMD_IDLE, null);
629             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
630 
631             // Now that we should be off the temp whitelist, make sure we again can't start.
632             failed = false;
633             try {
634                 mContext.startService(serviceIntent);
635             } catch (IllegalStateException e) {
636                 failed = true;
637             }
638             if (!failed) {
639                 fail("Service was allowed to start while in the background");
640             }
641 
642             // Now put app on whitelist, should allow service to run.
643             cmd = "cmd deviceidle whitelist +" + SIMPLE_PACKAGE_NAME;
644             result = SystemUtil.runShellCommand(mInstrumentation, cmd);
645 
646             // Try starting the service now that the app is whitelisted...  should work!
647             mContext.startService(serviceIntent);
648             conn.waitForConnect();
649 
650             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
651             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
652 
653             // Okay, bring down the service.
654             mContext.stopService(serviceIntent);
655             conn.waitForDisconnect();
656 
657             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
658             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
659 
660         } finally {
661             mContext.stopService(serviceIntent);
662             conn.stopMonitoring();
663 
664             uidWatcher.finish();
665 
666             cmd = "appops set --user " + userId + " "
667                     + SIMPLE_PACKAGE_NAME + " RUN_IN_BACKGROUND allow";
668             result = SystemUtil.runShellCommand(mInstrumentation, cmd);
669             cmd = "cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME;
670             result = SystemUtil.runShellCommand(mInstrumentation, cmd);
671 
672             uidGoneListener.unregister();
673             uidForegroundListener.unregister();
674 
675             data.recycle();
676         }
677     }
678 
679     /**
680      * Test that background check behaves correctly after a process is no longer foreground: first
681      * allowing a service to be started, then stopped by the system when idle.
682      */
683     @Test
testBackgroundCheckStopsService()684     public void testBackgroundCheckStopsService() throws Exception {
685         final Parcel data = Parcel.obtain();
686         ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext, mServiceIntent,
687                 WAIT_TIME);
688         ServiceConnectionHandler conn2 = new ServiceConnectionHandler(mContext, mService2Intent,
689                 WAIT_TIME);
690 
691         ActivityManager am = mContext.getSystemService(ActivityManager.class);
692 
693         PermissionUtils.grantPermission(
694                 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS);
695         /*
696         Log.d("XXXX", "Invoke: " + cmd);
697         Log.d("XXXX", "Result: " + result);
698         Log.d("XXXX", SystemUtil.runShellCommand(mInstrumentation, "dumpsys package "
699                 + STUB_PACKAGE_NAME));
700         */
701 
702         ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo(
703                 SIMPLE_PACKAGE_NAME, 0);
704 
705         UidImportanceListener uidServiceListener = new UidImportanceListener(mContext,
706                 appInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE, WAIT_TIME);
707         uidServiceListener.register();
708         UidImportanceListener uidGoneListener = new UidImportanceListener(mContext,
709                 appInfo.uid, IMPORTANCE_CACHED, WAIT_TIME);
710         uidGoneListener.register();
711 
712         WatchUidRunner uidWatcher = new WatchUidRunner(mInstrumentation, appInfo.uid,
713                 WAIT_TIME);
714 
715         // First kill the process to start out in a stable state.
716         mContext.stopService(mServiceIntent);
717         mContext.stopService(mService2Intent);
718         conn.bind();
719         conn2.bind();
720         IBinder service = conn.getServiceIBinder();
721         IBinder service2 = conn2.getServiceIBinder();
722         conn.unbind();
723         conn2.unbind();
724         try {
725             service.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0);
726         } catch (RemoteException e) {
727         }
728         try {
729             service2.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0);
730         } catch (RemoteException e) {
731         }
732         service = service2 = null;
733 
734         // Wait for uid's process to go away.
735         uidGoneListener.waitForValue(IMPORTANCE_GONE,
736                 IMPORTANCE_GONE);
737         assertEquals(IMPORTANCE_GONE,
738                 am.getPackageImportance(SIMPLE_PACKAGE_NAME));
739 
740         // And wait for the uid report to be gone.
741         uidWatcher.waitFor(WatchUidRunner.CMD_GONE, null, WAIT_TIME);
742 
743         String cmd = "appops set " + SIMPLE_PACKAGE_NAME + " RUN_IN_BACKGROUND deny";
744         String result = SystemUtil.runShellCommand(mInstrumentation, cmd);
745 
746         // This is a side-effect of the app op command.
747         uidWatcher.expect(WatchUidRunner.CMD_IDLE, null);
748         uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_NONEXISTENT);
749 
750         // We don't want to wait for the uid to actually go idle, we can force it now.
751         cmd = "am make-uid-idle " + SIMPLE_PACKAGE_NAME;
752         result = SystemUtil.runShellCommand(mInstrumentation, cmd);
753 
754         // Make sure app is not yet on whitelist
755         cmd = "cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME;
756         result = SystemUtil.runShellCommand(mInstrumentation, cmd);
757 
758         // We will use this to monitor when the service is running.
759         conn.startMonitoring();
760 
761         try {
762             // Try starting the service.  Should fail!
763             boolean failed = false;
764             try {
765                 mContext.startService(mServiceIntent);
766             } catch (IllegalStateException e) {
767                 failed = true;
768             }
769             if (!failed) {
770                 fail("Service was allowed to start while in the background");
771             }
772 
773             // First poke the process into the foreground, so we can avoid background check.
774             conn2.bind();
775             conn2.waitForConnect();
776 
777             // Wait for process state to reflect running service.
778             uidServiceListener.waitForValue(
779                     IMPORTANCE_FOREGROUND_SERVICE,
780                     ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE);
781             assertEquals(IMPORTANCE_FOREGROUND_SERVICE,
782                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
783 
784             // Also make sure the uid state reports are as expected.
785             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
786             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
787             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
788 
789             conn2.unbind();
790 
791             // Wait for process to recover back down to being cached.
792             uidServiceListener.waitForValue(IMPORTANCE_CACHED,
793                     IMPORTANCE_GONE);
794             assertEquals(IMPORTANCE_CACHED,
795                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
796 
797             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null);
798             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
799 
800             // Try starting the service now that the app is waiting to idle...  should work!
801             mContext.startService(mServiceIntent);
802             conn.waitForConnect();
803 
804             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
805             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
806 
807             // And also start the second service.
808             conn2.startMonitoring();
809             mContext.startService(mService2Intent);
810             conn2.waitForConnect();
811 
812             // Force app to go idle now
813             cmd = "am make-uid-idle " + SIMPLE_PACKAGE_NAME;
814             result = SystemUtil.runShellCommand(mInstrumentation, cmd);
815 
816             // Wait for services to be stopped by system.
817             uidServiceListener.waitForValue(IMPORTANCE_CACHED,
818                     IMPORTANCE_GONE);
819             assertEquals(IMPORTANCE_CACHED,
820                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
821 
822             // And service should be stopped by system, so just make sure it is disconnected.
823             conn.waitForDisconnect();
824             conn2.waitForDisconnect();
825 
826             uidWatcher.expect(WatchUidRunner.CMD_IDLE, null);
827             // There may be a transient 'SVC' proc state here.
828             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null);
829             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
830 
831         } finally {
832             mContext.stopService(mServiceIntent);
833             mContext.stopService(mService2Intent);
834             conn.cleanup();
835             conn2.cleanup();
836 
837             uidWatcher.finish();
838 
839             cmd = "appops set " + SIMPLE_PACKAGE_NAME + " RUN_IN_BACKGROUND allow";
840             result = SystemUtil.runShellCommand(mInstrumentation, cmd);
841             cmd = "cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME;
842             result = SystemUtil.runShellCommand(mInstrumentation, cmd);
843 
844             uidGoneListener.unregister();
845             uidServiceListener.unregister();
846 
847             data.recycle();
848         }
849     }
850 
851     /**
852      * Test the background check doesn't allow services to be started from broadcasts except when in
853      * the correct states.
854      */
855     @Test
testBackgroundCheckBroadcastService()856     public void testBackgroundCheckBroadcastService() throws Exception {
857         final Intent broadcastIntent = new Intent();
858         broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
859         broadcastIntent.setClassName(SIMPLE_PACKAGE_NAME,
860                 SIMPLE_PACKAGE_NAME + SIMPLE_RECEIVER_START_SERVICE);
861 
862         PermissionUtils.grantPermission(
863                 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS);
864         final ServiceProcessController controller = new ServiceProcessController(mContext,
865                 mInstrumentation, STUB_PACKAGE_NAME, mAllProcesses, WAIT_TIME);
866         final ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext,
867                 mServiceIntent, WAIT_TIME);
868         final WatchUidRunner uidWatcher = controller.getUidWatcher();
869 
870         try {
871             // First kill the process to start out in a stable state.
872             controller.ensureProcessGone();
873 
874             // Do initial setup.
875             controller.denyBackgroundOp();
876             controller.makeUidIdle();
877             controller.removeFromWhitelist();
878 
879             // We will use this to monitor when the service is running.
880             conn.startMonitoring();
881 
882             // Try sending broadcast to start the service.  Should fail!
883             SyncOrderedBroadcast br = new SyncOrderedBroadcast();
884             broadcastIntent.putExtra("service", mServiceIntent);
885             br.sendAndWait(mContext, broadcastIntent, Activity.RESULT_OK, null, null, WAIT_TIME);
886             int brCode = br.getReceivedCode();
887             if (brCode != Activity.RESULT_CANCELED) {
888                 fail("Didn't fail starting service, result=" + brCode);
889             }
890 
891             // Track the uid proc state changes from the broadcast (but not service execution)
892             uidWatcher.waitFor(WatchUidRunner.CMD_IDLE, null, WAIT_TIME);
893             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
894             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_RECEIVER,
895                     WAIT_TIME);
896             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null, WAIT_TIME);
897             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY,
898                     WAIT_TIME);
899 
900             // Put app on temporary whitelist to see if this allows the service start.
901             controller.tempWhitelist(TEMP_WHITELIST_DURATION_MS);
902 
903             // Being on the whitelist means the uid is now active.
904             uidWatcher.expect(WatchUidRunner.CMD_ACTIVE, null, WAIT_TIME);
905             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY,
906                     WAIT_TIME);
907 
908             // Try starting the service now that the app is whitelisted...  should work!
909             br.sendAndWait(mContext, broadcastIntent, Activity.RESULT_OK, null, null, WAIT_TIME);
910             brCode = br.getReceivedCode();
911             if (brCode != Activity.RESULT_FIRST_USER) {
912                 fail("Failed starting service, result=" + brCode);
913             }
914             conn.waitForConnect();
915 
916             // Also make sure the uid state reports are as expected.
917             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
918             // We are going to wait until 'SVC', because we may see an intermediate 'RCVR'
919             // proc state depending on timing.
920             uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
921 
922             // Good, now stop the service and give enough time to get off the temp whitelist.
923             mContext.stopService(mServiceIntent);
924             conn.waitForDisconnect();
925 
926             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
927             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
928 
929             controller.removeFromTempWhitelist();
930 
931             // Going off the temp whitelist causes a spurious proc state report...  that's
932             // not ideal, but okay.
933             // uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
934 
935             // We don't want to wait for the uid to actually go idle, we can force it now.
936             controller.makeUidIdle();
937 
938             uidWatcher.expect(WatchUidRunner.CMD_IDLE, null);
939 
940             // Make sure the process is gone so we start over fresh.
941             controller.ensureProcessGone();
942 
943             // Now that we should be off the temp whitelist, make sure we again can't start.
944             br.sendAndWait(mContext, broadcastIntent, Activity.RESULT_OK, null, null, WAIT_TIME);
945             brCode = br.getReceivedCode();
946             if (brCode != Activity.RESULT_CANCELED) {
947                 fail("Didn't fail starting service, result=" + brCode);
948             }
949 
950             // Track the uid proc state changes from the broadcast (but not service execution)
951             uidWatcher.waitFor(WatchUidRunner.CMD_IDLE, null);
952             // There could be a transient 'cached' state here before 'uncached' if uid state
953             // changes are dispatched before receiver is started.
954             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
955             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_RECEIVER);
956             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
957             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
958 
959             // Now put app on whitelist, should allow service to run.
960             controller.addToWhitelist();
961 
962             // Try starting the service now that the app is whitelisted...  should work!
963             br.sendAndWait(mContext, broadcastIntent, Activity.RESULT_OK, null, null, WAIT_TIME);
964             brCode = br.getReceivedCode();
965             if (brCode != Activity.RESULT_FIRST_USER) {
966                 fail("Failed starting service, result=" + brCode);
967             }
968             conn.waitForConnect();
969 
970             // Also make sure the uid state reports are as expected.
971             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
972             uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
973 
974             // Okay, bring down the service.
975             mContext.stopService(mServiceIntent);
976             conn.waitForDisconnect();
977 
978             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
979             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
980 
981         } finally {
982             mContext.stopService(mServiceIntent);
983             conn.stopMonitoringIfNeeded();
984             controller.cleanup();
985         }
986     }
987 
988     /**
989      * Test that background check does allow services to be started from activities.
990      */
991     @Test
testBackgroundCheckActivityService()992     public void testBackgroundCheckActivityService() throws Exception {
993         final Intent activityIntent = new Intent();
994         activityIntent.setClassName(SIMPLE_PACKAGE_NAME,
995                 SIMPLE_PACKAGE_NAME + SIMPLE_ACTIVITY_START_SERVICE);
996         activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
997 
998         PermissionUtils.grantPermission(
999                 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS);
1000         final ServiceProcessController controller = new ServiceProcessController(mContext,
1001                 mInstrumentation, STUB_PACKAGE_NAME, mAllProcesses, WAIT_TIME);
1002         final ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext,
1003                 mServiceIntent, WAIT_TIME);
1004         final WatchUidRunner uidWatcher = controller.getUidWatcher();
1005 
1006         try {
1007             // First kill the process to start out in a stable state.
1008             controller.ensureProcessGone();
1009 
1010             // Do initial setup.
1011             controller.denyBackgroundOp();
1012             controller.makeUidIdle();
1013             controller.removeFromWhitelist();
1014 
1015             // We will use this to monitor when the service is running.
1016             conn.startMonitoring();
1017 
1018             // Try starting activity that will start the service.  This should be okay.
1019             WaitForBroadcast waiter = new WaitForBroadcast(mInstrumentation.getTargetContext());
1020             waiter.prepare(ACTION_SIMPLE_ACTIVITY_START_SERVICE_RESULT);
1021             activityIntent.putExtra("service", mServiceIntent);
1022             startActivity(mTargetContext, activityIntent);
1023             Intent resultIntent = waiter.doWait(WAIT_TIME * 2);
1024             int brCode = resultIntent.getIntExtra("result", Activity.RESULT_CANCELED);
1025             if (brCode != Activity.RESULT_FIRST_USER) {
1026                 fail("Failed starting service, result=" + brCode);
1027             }
1028             conn.waitForConnect();
1029 
1030             final String expectedActivityState = (CtsAppTestUtils.isScreenInteractive(mContext)
1031                     && !CtsAppTestUtils.isKeyguardLocked(mContext))
1032                     ? WatchUidRunner.STATE_TOP : WatchUidRunner.STATE_TOP_SLEEPING;
1033             // Also make sure the uid state reports are as expected.
1034             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
1035             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1036             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, expectedActivityState);
1037             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
1038 
1039             // Okay, bring down the service.
1040             mContext.stopService(mServiceIntent);
1041             conn.waitForDisconnect();
1042 
1043             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
1044             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1045 
1046             // App isn't yet idle, so we should be able to start the service again.
1047             mContext.startService(mServiceIntent);
1048             conn.waitForConnect();
1049             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1050             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
1051 
1052             // And now fast-forward to the app going idle, service should be stopped.
1053             controller.makeUidIdle();
1054             uidWatcher.waitFor(WatchUidRunner.CMD_IDLE, null);
1055 
1056             conn.waitForDisconnect();
1057             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null);
1058             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1059 
1060             // No longer should be able to start service.
1061             boolean failed = false;
1062             try {
1063                 mContext.startService(mServiceIntent);
1064             } catch (IllegalStateException e) {
1065                 failed = true;
1066             }
1067             if (!failed) {
1068                 fail("Service was allowed to start while in the background");
1069             }
1070 
1071         } finally {
1072             mContext.stopService(mServiceIntent);
1073             conn.stopMonitoringIfNeeded();
1074             controller.cleanup();
1075         }
1076     }
1077 
1078     /**
1079      * Test that the foreground service app op does prevent the foreground state.
1080      */
1081     @Test
testForegroundServiceAppOp()1082     public void testForegroundServiceAppOp() throws Exception {
1083         PermissionUtils.grantPermission(
1084                 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS);
1085         // Use default timeout value 5000
1086         final ServiceProcessController controller = new ServiceProcessController(mContext,
1087                 mInstrumentation, STUB_PACKAGE_NAME, mAllProcesses);
1088         // Use default timeout value 5000
1089         final ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext,
1090                 mServiceIntent);
1091         final WatchUidRunner uidWatcher = controller.getUidWatcher();
1092 
1093         try {
1094             // First kill the process to start out in a stable state.
1095             controller.ensureProcessGone();
1096 
1097             // Do initial setup.
1098             controller.makeUidIdle();
1099             controller.removeFromWhitelist();
1100             controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "allow");
1101 
1102             // Put app on whitelist, to allow service to run.
1103             controller.addToWhitelist();
1104 
1105             // We will use this to monitor when the service is running.
1106             conn.startMonitoring();
1107 
1108             // -------- START SERVICE AND THEN SUCCESSFULLY GO TO FOREGROUND
1109 
1110             // Now start the service and wait for it to come up.
1111             mContext.startService(mServiceStartForegroundIntent);
1112             conn.waitForConnect();
1113 
1114             // Also make sure the uid state reports are as expected.
1115             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1116             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
1117             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
1118             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1119 
1120             // Now take it out of foreground and confirm.
1121             mContext.startService(mServiceStopForegroundIntent);
1122             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
1123 
1124             // Good, now stop the service and wait for it to go away.
1125             mContext.stopService(mServiceStartForegroundIntent);
1126             conn.waitForDisconnect();
1127 
1128             // There may be a transient STATE_SERVICE we don't care about, so waitFor.
1129             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null);
1130             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1131 
1132             // We don't want to wait for the uid to actually go idle, we can force it now.
1133             controller.makeUidIdle();
1134             uidWatcher.expect(WatchUidRunner.CMD_IDLE, null);
1135 
1136             // Make sure the process is gone so we start over fresh.
1137             controller.ensureProcessGone();
1138 
1139             // -------- START SERVICE AND BLOCK GOING TO FOREGROUND
1140 
1141             // Now we will deny the app op and ensure the service can't become foreground.
1142             controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "ignore");
1143 
1144             // Now start the service and wait for it to come up.
1145             mContext.startService(mServiceStartForegroundIntent);
1146             conn.waitForConnect();
1147 
1148             // Also make sure the uid state reports are as expected.
1149             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1150             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
1151 
1152             // Good, now stop the service and wait for it to go away.
1153             mContext.stopService(mServiceStartForegroundIntent);
1154             conn.waitForDisconnect();
1155 
1156             // THIS MUST BE AN EXPECT: we want to make sure we don't get in to STATE_FG_SERVICE.
1157             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
1158             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1159 
1160             // Make sure the uid is idle (it should be anyway, it never went active here).
1161             controller.makeUidIdle();
1162 
1163             // Make sure the process is gone so we start over fresh.
1164             controller.ensureProcessGone();
1165 
1166             // -------- DIRECT START FOREGROUND SERVICE SUCCESSFULLY
1167 
1168             controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "allow");
1169 
1170             // Now start the service and wait for it to come up.
1171             mContext.startForegroundService(mServiceStartForegroundIntent);
1172             conn.waitForConnect();
1173 
1174             // Make sure it becomes a foreground service.  The process state changes here
1175             // are weird looking because we first need to force the app out of idle to allow
1176             // it to start the service.
1177             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
1178             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1179             uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1180             // Remove tempwhitelist avoid temp white list block idle command and app crash occur.
1181             CtsAppTestUtils.executeShellCmd(mInstrumentation,
1182                     "cmd deviceidle tempwhitelist -r " + SIMPLE_PACKAGE_NAME);
1183             // Good, now stop the service and wait for it to go away.
1184             mContext.stopService(mServiceStartForegroundIntent);
1185             conn.waitForDisconnect();
1186 
1187             // There may be a transient STATE_SERVICE we don't care about, so waitFor.
1188             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null);
1189             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1190 
1191             // We don't want to wait for the uid to actually go idle, we can force it now.
1192             controller.makeUidIdle();
1193 
1194             // Make sure the process is gone so we start over fresh.
1195             controller.ensureProcessGone();
1196 
1197             // -------- DIRECT START FOREGROUND SERVICE BLOCKED
1198 
1199             // Now we will deny the app op and ensure the service can't become foreground.
1200             controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "ignore");
1201 
1202             // But we will put it on the whitelist so the service is still allowed to start.
1203             controller.addToWhitelist();
1204 
1205             // Now start the service and wait for it to come up.
1206             mContext.startForegroundService(mServiceStartForegroundIntent);
1207             conn.waitForConnect();
1208 
1209             // In this case we only get to run it as a regular service.
1210             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1211             uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
1212 
1213             // Good, now stop the service and wait for it to go away.
1214             mContext.stopService(mServiceStartForegroundIntent);
1215             conn.waitForDisconnect();
1216 
1217             // THIS MUST BE AN EXPECT: we want to make sure we don't get in to STATE_FG_SERVICE.
1218             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
1219             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1220 
1221             // Make sure the uid is idle (it should be anyway, it never went active here).
1222             controller.makeUidIdle();
1223 
1224             // Make sure the process is gone so we start over fresh.
1225             controller.ensureProcessGone();
1226 
1227             // -------- XXX NEED TO TEST NON-WHITELIST CASE WHERE NOTHING HAPPENS
1228 
1229         } finally {
1230             mContext.stopService(mServiceStartForegroundIntent);
1231             conn.stopMonitoringIfNeeded();
1232             controller.cleanup();
1233             controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "allow");
1234             controller.removeFromWhitelist();
1235         }
1236     }
1237 
1238     /**
1239      * Verify that an app under background restrictions has its foreground services demoted to
1240      * ordinary service state when it is no longer the top app.
1241      */
1242     @Test
testBgRestrictedForegroundService()1243     public void testBgRestrictedForegroundService() throws Exception {
1244         final Intent activityIntent = new Intent()
1245                 .setClassName(SIMPLE_PACKAGE_NAME,
1246                         SIMPLE_PACKAGE_NAME + SIMPLE_ACTIVITY_START_FG_SERVICE)
1247                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1248 
1249         PermissionUtils.grantPermission(
1250                 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS);
1251         final ServiceProcessController controller = new ServiceProcessController(mContext,
1252                 mInstrumentation, STUB_PACKAGE_NAME, mAllProcesses, WAIT_TIME);
1253         final WatchUidRunner uidWatcher = controller.getUidWatcher();
1254 
1255         final Intent homeIntent = new Intent()
1256                 .setAction(Intent.ACTION_MAIN)
1257                 .addCategory(Intent.CATEGORY_HOME)
1258                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
1259                         | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
1260 
1261         final Intent serviceStartIntent = new Intent(mService3Intent)
1262                 .setAction(ACTION_START_THEN_FG);
1263         activityIntent.putExtra("service", serviceStartIntent);
1264         boolean activityStarted = false;
1265 
1266         try {
1267             // First kill the process to start out in a stable state.
1268             controller.ensureProcessGone();
1269 
1270             // Do initial setup.
1271             controller.denyAnyInBackgroundOp();
1272             controller.makeUidIdle();
1273             controller.removeFromWhitelist();
1274             controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "allow");
1275 
1276             // Start the activity, which will start the fg service as well, and wait
1277             // for the report that it's all up and running.
1278             WaitForBroadcast waiter = new WaitForBroadcast(mInstrumentation.getTargetContext());
1279             waiter.prepare(ACTION_SIMPLE_ACTIVITY_START_FG_SERVICE_RESULT);
1280 
1281             activityIntent.setAction(ACTION_SIMPLE_ACTIVITY_START_FG);
1282             startActivity(mTargetContext, activityIntent);
1283             activityStarted = true;
1284 
1285             Intent resultIntent = waiter.doWait(WAIT_TIME);
1286             int brCode = resultIntent.getIntExtra("result", Activity.RESULT_CANCELED);
1287             if (brCode != Activity.RESULT_FIRST_USER) {
1288                 fail("Failed starting service, result=" + brCode);
1289             }
1290 
1291             // activity is in front, fg service is running.  make sure that we see
1292             // the expected state at this point.
1293             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
1294             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1295             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP);
1296 
1297             // Switch to the home app; make sure the test app drops all the way
1298             // down to SERVICE, not FG_SERVICE
1299             mTargetContext.startActivity(homeIntent);
1300             uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
1301         } finally {
1302             // tear down everything and we're done
1303             if (activityStarted) {
1304                 activityIntent.setAction(ACTION_FINISH_EVERYTHING);
1305                 mTargetContext.startActivity(activityIntent);
1306             }
1307 
1308             controller.cleanup();
1309         }
1310 
1311     }
1312 
supportsCantSaveState()1313     private boolean supportsCantSaveState() {
1314         if (mContext.getPackageManager().hasSystemFeature(
1315                 PackageManager.FEATURE_CANT_SAVE_STATE)) {
1316             return true;
1317         }
1318 
1319         return false;
1320     }
1321 
1322     /**
1323      * Test that a single "can't save state" app has the proper process management semantics.
1324      */
1325     @Test
testCantSaveStateLaunchAndBackground()1326     public void testCantSaveStateLaunchAndBackground() throws Exception {
1327         if (!supportsCantSaveState()) {
1328             return;
1329         }
1330 
1331         final Intent activityIntent = new Intent();
1332         activityIntent.setPackage(CANT_SAVE_STATE_1_PACKAGE_NAME);
1333         activityIntent.setAction(Intent.ACTION_MAIN);
1334         activityIntent.addCategory(Intent.CATEGORY_LAUNCHER);
1335         activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1336 
1337         final Intent homeIntent = new Intent();
1338         homeIntent.setAction(Intent.ACTION_MAIN);
1339         homeIntent.addCategory(Intent.CATEGORY_HOME);
1340         homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1341 
1342         ActivityManager am = mContext.getSystemService(ActivityManager.class);
1343 
1344         PermissionUtils.grantPermission(
1345                 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS);
1346 
1347         // We don't want to wait for the uid to actually go idle, we can force it now.
1348         String cmd = "am make-uid-idle " + CANT_SAVE_STATE_1_PACKAGE_NAME;
1349         String result = SystemUtil.runShellCommand(mInstrumentation, cmd);
1350 
1351         ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo(
1352                 CANT_SAVE_STATE_1_PACKAGE_NAME, 0);
1353 
1354         // This test is also using UidImportanceListener to make sure the correct
1355         // heavy-weight state is reported there.
1356         UidImportanceListener uidForegroundListener = new UidImportanceListener(mContext,
1357                 appInfo.uid, IMPORTANCE_FOREGROUND,
1358                 WAIT_TIME);
1359         uidForegroundListener.register();
1360         UidImportanceListener uidBackgroundListener = new UidImportanceListener(mContext,
1361                 appInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE - 1,
1362                 WAIT_TIME);
1363         uidBackgroundListener.register();
1364         UidImportanceListener uidCachedListener = new UidImportanceListener(mContext,
1365                 appInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE + 1,
1366                 WAIT_TIME);
1367         uidCachedListener.register();
1368 
1369         WatchUidRunner uidWatcher = new WatchUidRunner(mInstrumentation, appInfo.uid,
1370                 WAIT_TIME);
1371 
1372         UiDevice device = UiDevice.getInstance(mInstrumentation);
1373 
1374         try {
1375             // Start the heavy-weight app, should launch like a normal app.
1376             startActivity(mTargetContext, activityIntent);
1377             waitForAppFocus(CANT_SAVE_STATE_1_PACKAGE_NAME, WAIT_TIME);
1378             device.waitForIdle();
1379 
1380             // Wait for process state to reflect running activity.
1381             uidForegroundListener.waitForValue(
1382                     IMPORTANCE_FOREGROUND,
1383                     IMPORTANCE_FOREGROUND);
1384             assertEquals(IMPORTANCE_FOREGROUND,
1385                     am.getPackageImportance(CANT_SAVE_STATE_1_PACKAGE_NAME));
1386 
1387             // Also make sure the uid state reports are as expected.
1388             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
1389             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1390             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP);
1391 
1392             // Now go to home, leaving the app.  It should be put in the heavy weight state.
1393             mTargetContext.startActivity(homeIntent);
1394             final WindowManagerStateHelper wms = new WindowManagerStateHelper();
1395             wms.waitForHomeActivityVisible();
1396 
1397             final int expectedImportance =
1398                     (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O)
1399                             ? ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE
1400                             : ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE_PRE_26;
1401             // Wait for process to go down to background heavy-weight.
1402             uidBackgroundListener.waitForValue(expectedImportance, expectedImportance);
1403             assertEquals(expectedImportance,
1404                     am.getPackageImportance(CANT_SAVE_STATE_1_PACKAGE_NAME));
1405 
1406             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null);
1407             uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_HEAVY_WEIGHT);
1408 
1409             // While in background, should go in to normal idle state.
1410             // Force app to go idle now
1411             cmd = "am make-uid-idle " + CANT_SAVE_STATE_1_PACKAGE_NAME;
1412             result = SystemUtil.runShellCommand(mInstrumentation, cmd);
1413             uidWatcher.waitFor(WatchUidRunner.CMD_IDLE, null);
1414 
1415             // Switch back to heavy-weight app to see if it correctly returns to foreground.
1416             startActivity(mTargetContext, activityIntent);
1417 
1418             // Wait for process state to reflect running activity.
1419             uidForegroundListener.waitForValue(
1420                     IMPORTANCE_FOREGROUND,
1421                     IMPORTANCE_FOREGROUND);
1422             assertEquals(IMPORTANCE_FOREGROUND,
1423                     am.getPackageImportance(CANT_SAVE_STATE_1_PACKAGE_NAME));
1424 
1425             // Also make sure the uid state reports are as expected.
1426             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
1427             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1428             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP);
1429 
1430             waitForAppFocus(CANT_SAVE_STATE_1_PACKAGE_NAME, WAIT_TIME);
1431             device.waitForIdle();
1432 
1433             // Exit activity, check to see if we are now cached.
1434             final Intent finishIntent = new Intent();
1435             finishIntent.setPackage(CANT_SAVE_STATE_1_PACKAGE_NAME);
1436             finishIntent.setAction(ACTION_FINISH);
1437             finishIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1438             finishIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
1439             mTargetContext.startActivity(finishIntent);
1440 
1441             // Wait for process to become cached
1442             uidCachedListener.waitForValue(
1443                     IMPORTANCE_CACHED,
1444                     IMPORTANCE_CACHED);
1445             assertEquals(IMPORTANCE_CACHED,
1446                     am.getPackageImportance(CANT_SAVE_STATE_1_PACKAGE_NAME));
1447 
1448             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
1449             uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_RECENT);
1450 
1451             // While in background, should go in to normal idle state.
1452             // Force app to go idle now
1453             cmd = "am make-uid-idle " + CANT_SAVE_STATE_1_PACKAGE_NAME;
1454             result = SystemUtil.runShellCommand(mInstrumentation, cmd);
1455             uidWatcher.expect(WatchUidRunner.CMD_IDLE, null);
1456 
1457         } finally {
1458             uidWatcher.finish();
1459             uidForegroundListener.unregister();
1460             uidBackgroundListener.unregister();
1461             uidCachedListener.unregister();
1462         }
1463     }
1464 
1465     /**
1466      * Test that switching between two "can't save state" apps is handled properly.
1467      */
1468     @Test
testCantSaveStateLaunchAndSwitch()1469     public void testCantSaveStateLaunchAndSwitch() throws Exception {
1470         if (!supportsCantSaveState()) {
1471             return;
1472         }
1473 
1474         final Intent activity1Intent = new Intent();
1475         activity1Intent.setPackage(CANT_SAVE_STATE_1_PACKAGE_NAME);
1476         activity1Intent.setAction(Intent.ACTION_MAIN);
1477         activity1Intent.addCategory(Intent.CATEGORY_LAUNCHER);
1478         activity1Intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1479 
1480         final Intent activity2Intent = new Intent();
1481         activity2Intent.setPackage(CANT_SAVE_STATE_2_PACKAGE_NAME);
1482         activity2Intent.setAction(Intent.ACTION_MAIN);
1483         activity2Intent.addCategory(Intent.CATEGORY_LAUNCHER);
1484         activity2Intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1485 
1486         final Intent homeIntent = new Intent();
1487         homeIntent.setAction(Intent.ACTION_MAIN);
1488         homeIntent.addCategory(Intent.CATEGORY_HOME);
1489         homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1490 
1491         UiDevice device = UiDevice.getInstance(mInstrumentation);
1492 
1493         PermissionUtils.grantPermission(
1494                 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS);
1495 
1496         // We don't want to wait for the uid to actually go idle, we can force it now.
1497         String cmd = "am make-uid-idle " + CANT_SAVE_STATE_1_PACKAGE_NAME;
1498         String result = SystemUtil.runShellCommand(mInstrumentation, cmd);
1499         cmd = "am make-uid-idle " + CANT_SAVE_STATE_2_PACKAGE_NAME;
1500         result = SystemUtil.runShellCommand(mInstrumentation, cmd);
1501 
1502         ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo(
1503                 CANT_SAVE_STATE_1_PACKAGE_NAME, 0);
1504         WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid,
1505                 WAIT_TIME);
1506 
1507         ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo(
1508                 CANT_SAVE_STATE_2_PACKAGE_NAME, 0);
1509         WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid,
1510                 WAIT_TIME);
1511 
1512         try {
1513             // Start the first heavy-weight app, should launch like a normal app.
1514             startActivity(mTargetContext, activity1Intent);
1515             waitForAppFocus(CANT_SAVE_STATE_1_PACKAGE_NAME, WAIT_TIME);
1516             device.waitForIdle();
1517 
1518             // Make sure the uid state reports are as expected.
1519             uid1Watcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
1520             uid1Watcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1521             uid1Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP);
1522 
1523             // Now go to home, leaving the app.  It should be put in the heavy weight state.
1524             mTargetContext.startActivity(homeIntent);
1525             final WindowManagerStateHelper wms = new WindowManagerStateHelper();
1526             wms.waitForHomeActivityVisible();
1527 
1528             // Wait for process to go down to background heavy-weight.
1529             uid1Watcher.expect(WatchUidRunner.CMD_CACHED, null);
1530             uid1Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_HEAVY_WEIGHT);
1531 
1532             // Start the second heavy-weight app, should ask us what to do with the two apps
1533             startAndWaitForHeavyWeightSwitcherActivity(activity2Intent);
1534 
1535             // First, let's try returning to the original app.
1536             maybeClick(device, new UiSelector().resourceId("android:id/switch_old"));
1537             waitForAppFocus(CANT_SAVE_STATE_1_PACKAGE_NAME, WAIT_TIME);
1538             device.waitForIdle();
1539 
1540             // App should now be back in foreground.
1541             uid1Watcher.expect(WatchUidRunner.CMD_UNCACHED, null);
1542             uid1Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP);
1543 
1544             // Return to home.
1545             mTargetContext.startActivity(homeIntent);
1546             uid1Watcher.expect(WatchUidRunner.CMD_CACHED, null);
1547             uid1Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_HEAVY_WEIGHT);
1548 
1549             // Again try starting second heavy-weight app to get prompt.
1550             startAndWaitForHeavyWeightSwitcherActivity(activity2Intent);
1551 
1552             // Now we'll switch to the new app.
1553             maybeClick(device, new UiSelector().resourceId("android:id/switch_new"));
1554             waitForAppFocus(CANT_SAVE_STATE_2_PACKAGE_NAME, WAIT_TIME);
1555             device.waitForIdle();
1556 
1557             // The original app should now become cached.
1558             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_RECENT);
1559 
1560             // And the new app should start.
1561             uid2Watcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
1562             uid2Watcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1563             uid2Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP);
1564 
1565             // Make sure the original app is idle for cleanliness
1566             cmd = "am make-uid-idle " + CANT_SAVE_STATE_1_PACKAGE_NAME;
1567             result = SystemUtil.runShellCommand(mInstrumentation, cmd);
1568             uid1Watcher.expect(WatchUidRunner.CMD_IDLE, null);
1569 
1570             // We are interested in only the uid changes happening after returning to home.
1571             // Clear the history so we won't match staled results.
1572             device.waitForIdle();
1573             uid2Watcher.clearHistory();
1574             // Return to home.
1575             mTargetContext.startActivity(homeIntent);
1576             uid2Watcher.waitFor(WatchUidRunner.CMD_CACHED, null);
1577             uid2Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_HEAVY_WEIGHT);
1578 
1579             // Try starting the first heavy weight app, but return to the existing second.
1580             startAndWaitForHeavyWeightSwitcherActivity(activity1Intent);
1581             maybeClick(device, new UiSelector().resourceId("android:id/switch_old"));
1582             waitForAppFocus(CANT_SAVE_STATE_2_PACKAGE_NAME, WAIT_TIME);
1583             device.waitForIdle();
1584             uid2Watcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1585             uid2Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP);
1586 
1587             // Return to home.
1588             mTargetContext.startActivity(homeIntent);
1589             uid2Watcher.waitFor(WatchUidRunner.CMD_CACHED, null);
1590             uid2Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_HEAVY_WEIGHT);
1591 
1592             // Again start the first heavy weight app, this time actually switching to it
1593             startAndWaitForHeavyWeightSwitcherActivity(activity1Intent);
1594             maybeClick(device, new UiSelector().resourceId("android:id/switch_new"));
1595             waitForAppFocus(CANT_SAVE_STATE_1_PACKAGE_NAME, WAIT_TIME);
1596             device.waitForIdle();
1597 
1598             // The second app should now become cached.
1599             uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_RECENT);
1600 
1601             // And the first app should start.
1602             uid1Watcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
1603             uid1Watcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1604             uid1Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP);
1605 
1606             waitForAppFocus(CANT_SAVE_STATE_1_PACKAGE_NAME, WAIT_TIME);
1607             device.waitForIdle();
1608 
1609             // Exit activity, check to see if we are now cached.
1610             final Intent finishIntent = new Intent();
1611             finishIntent.setPackage(CANT_SAVE_STATE_1_PACKAGE_NAME);
1612             finishIntent.setAction(ACTION_FINISH);
1613             finishIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1614             finishIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
1615             mTargetContext.startActivity(finishIntent);
1616 
1617             uid1Watcher.expect(WatchUidRunner.CMD_CACHED, null);
1618             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_RECENT);
1619 
1620             // Make both apps idle for cleanliness.
1621             cmd = "am make-uid-idle " + CANT_SAVE_STATE_1_PACKAGE_NAME;
1622             result = SystemUtil.runShellCommand(mInstrumentation, cmd);
1623             cmd = "am make-uid-idle " + CANT_SAVE_STATE_2_PACKAGE_NAME;
1624             result = SystemUtil.runShellCommand(mInstrumentation, cmd);
1625 
1626         } finally {
1627             uid2Watcher.finish();
1628             uid1Watcher.finish();
1629         }
1630     }
1631 
1632     /**
1633      * Test a service binding cycle between two apps, with one of them also running a foreground
1634      * service. The other app should also get an FGS proc state. On stopping the foreground service,
1635      * app should go back to cached state.
1636      *
1637      * @throws Exception
1638      */
1639     @Test
testCycleFgs()1640     public void testCycleFgs() throws Exception {
1641         ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo(
1642                 PACKAGE_NAME_APP1, 0);
1643         ApplicationInfo app3Info = mContext.getPackageManager().getApplicationInfo(
1644                 PACKAGE_NAME_APP3, 0);
1645         WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid,
1646                 WAITFOR_MSEC);
1647         WatchUidRunner uid3Watcher = new WatchUidRunner(mInstrumentation, app3Info.uid,
1648                 WAITFOR_MSEC);
1649 
1650         try {
1651             SystemUtil.runShellCommand(mInstrumentation,
1652                     "cmd deviceidle whitelist +" + PACKAGE_NAME_APP1);
1653             CommandReceiver.sendCommand(mContext,
1654                     CommandReceiver.COMMAND_START_FOREGROUND_SERVICE,
1655                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
1656             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1657 
1658             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1659                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP3, 0, null);
1660 
1661             uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1662 
1663             // Create a cycle
1664             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1665                     PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null);
1666 
1667             try {
1668                 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
1669                         WatchUidRunner.STATE_CACHED_EMPTY);
1670                 fail("App3 should not be demoted to cached");
1671             } catch (IllegalStateException ise) {
1672                 // Didn't go to cached in spite of cycle. Good!
1673             }
1674 
1675             // Stop the foreground service
1676             CommandReceiver.sendCommand(mContext, CommandReceiver
1677                             .COMMAND_STOP_FOREGROUND_SERVICE,
1678                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
1679 
1680             // Check that the app's proc state has fallen
1681             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1682             uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1683         } finally {
1684             // Clean up: unbind services to avoid from interferences with other tests
1685             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1686                     PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null);
1687             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1688                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP3, 0, null);
1689 
1690             SystemUtil.runShellCommand(mInstrumentation,
1691                     "cmd deviceidle whitelist -" + PACKAGE_NAME_APP1);
1692             uid1Watcher.finish();
1693             uid3Watcher.finish();
1694         }
1695     }
1696 
1697     /**
1698      * Test a service binding cycle between three apps, with one of them also running a foreground
1699      * service. The other apps should also get an FGS proc state. On stopping the foreground
1700      * service, app should go back to cached state.
1701      *
1702      * @throws Exception
1703      */
1704     @Test
testCycleFgsTriangle()1705     public void testCycleFgsTriangle() throws Exception {
1706         ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo(
1707                 PACKAGE_NAME_APP1, 0);
1708         ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo(
1709                 PACKAGE_NAME_APP2, 0);
1710         ApplicationInfo app3Info = mContext.getPackageManager().getApplicationInfo(
1711                 PACKAGE_NAME_APP3, 0);
1712         WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid,
1713                 WAITFOR_MSEC);
1714         WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid,
1715                 WAITFOR_MSEC);
1716         WatchUidRunner uid3Watcher = new WatchUidRunner(mInstrumentation, app3Info.uid,
1717                 WAITFOR_MSEC);
1718 
1719         try {
1720             SystemUtil.runShellCommand(mInstrumentation,
1721                     "cmd deviceidle whitelist +" + PACKAGE_NAME_APP1);
1722             CommandReceiver.sendCommand(mContext,
1723                     CommandReceiver.COMMAND_START_FOREGROUND_SERVICE,
1724                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
1725             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1726 
1727             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1728                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null);
1729 
1730             uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1731 
1732             // Bind from 2 to 3
1733             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1734                     PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null);
1735             uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1736 
1737             // Create a cycle
1738             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1739                     PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null);
1740 
1741             try {
1742                 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
1743                         WatchUidRunner.STATE_CACHED_EMPTY);
1744                 fail("App3 should not be demoted to cached");
1745             } catch (IllegalStateException ise) {
1746                 // Didn't go to cached in spite of cycle. Good!
1747             }
1748 
1749             try {
1750                 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
1751                         WatchUidRunner.STATE_CACHED_EMPTY);
1752                 fail("App2 should not be demoted to cached");
1753             } catch (IllegalStateException ise) {
1754                 // Didn't go to cached in spite of cycle. Good!
1755             }
1756 
1757             try {
1758                 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
1759                         WatchUidRunner.STATE_CACHED_EMPTY);
1760                 fail("App1 should not be demoted to cached");
1761             } catch (IllegalStateException ise) {
1762                 // Didn't go to cached in spite of cycle. Good!
1763             }
1764 
1765             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1766                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null);
1767 
1768             uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1769             uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1770         } finally {
1771             // Clean up: unbind services to avoid from interferences with other tests
1772             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1773                     PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null);
1774             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1775                     PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null);
1776             // Stop the foreground service
1777             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE,
1778                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
1779             SystemUtil.runShellCommand(mInstrumentation,
1780                     "cmd deviceidle whitelist -" + PACKAGE_NAME_APP1);
1781 
1782             uid1Watcher.finish();
1783             uid2Watcher.finish();
1784             uid3Watcher.finish();
1785         }
1786     }
1787 
1788     /**
1789      * Test a service binding cycle between three apps, with one of them also running a foreground
1790      * service. The other apps should also get an FGS proc state. On stopping the foreground
1791      * service, app should go back to cached state.
1792      *
1793      * @throws Exception
1794      */
1795     @Test
testCycleFgsTriangleBiDi()1796     public void testCycleFgsTriangleBiDi() throws Exception {
1797         ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo(
1798                 PACKAGE_NAME_APP1, 0);
1799         ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo(
1800                 PACKAGE_NAME_APP2, 0);
1801         ApplicationInfo app3Info = mContext.getPackageManager().getApplicationInfo(
1802                 PACKAGE_NAME_APP3, 0);
1803         WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid,
1804                 WAITFOR_MSEC);
1805         WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid,
1806                 WAITFOR_MSEC);
1807         WatchUidRunner uid3Watcher = new WatchUidRunner(mInstrumentation, app3Info.uid,
1808                 WAITFOR_MSEC);
1809 
1810         try {
1811             SystemUtil.runShellCommand(mInstrumentation,
1812                     "cmd deviceidle whitelist +" + PACKAGE_NAME_APP1);
1813             CommandReceiver.sendCommand(mContext,
1814                     CommandReceiver.COMMAND_START_FOREGROUND_SERVICE,
1815                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
1816             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1817 
1818             // Bind from 1 to 2, 1 to 3
1819             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1820                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null);
1821             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1822                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP3, 0, null);
1823 
1824             uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1825             uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1826 
1827             // Bind from 2 to 3, 3 to 2, 3 to 1
1828             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1829                     PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null);
1830             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1831                     PACKAGE_NAME_APP3, PACKAGE_NAME_APP2, 0, null);
1832             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1833                     PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null);
1834 
1835             try {
1836                 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
1837                         WatchUidRunner.STATE_CACHED_EMPTY);
1838                 fail("App3 should not be demoted to cached");
1839             } catch (IllegalStateException ise) {
1840                 // Didn't go to cached in spite of cycle. Good!
1841             }
1842 
1843             // Stop the foreground service
1844             CommandReceiver.sendCommand(mContext, CommandReceiver
1845                             .COMMAND_STOP_FOREGROUND_SERVICE,
1846                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
1847 
1848             // Check that the apps' proc state has fallen
1849             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1850             uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1851             uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1852         } finally {
1853             // Clean up: unbind services to avoid from interferences with other tests
1854             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1855                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null);
1856             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1857                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP3, 0, null);
1858             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1859                     PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null);
1860             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1861                     PACKAGE_NAME_APP3, PACKAGE_NAME_APP2, 0, null);
1862             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1863                     PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null);
1864 
1865             SystemUtil.runShellCommand(mInstrumentation,
1866                     "cmd deviceidle whitelist -" + PACKAGE_NAME_APP1);
1867 
1868             uid1Watcher.finish();
1869             uid2Watcher.finish();
1870             uid3Watcher.finish();
1871         }
1872     }
1873 
1874     /**
1875      * Test process states for foreground service binding to another app, with and without
1876      * BIND_INCLUDE_CAPABILITIES. With BIND_INCLUDE_CAPABILITIES flag,
1877      * PROCESS_CAPABILITY_FOREGROUND_LOCATION can be passed from client to service. Without
1878      * BIND_INCLUDE_CAPABILITIES flag, PROCESS_CAPABILITY_FOREGROUND_LOCATION can not be passed from
1879      * client to service.
1880      * @throws Exception
1881      */
1882     @Test
testFgsLocationBind()1883     public void testFgsLocationBind() throws Exception {
1884         setupWatchers(3);
1885 
1886         Bundle bundle = new Bundle();
1887         bundle.putInt(LocalForegroundServiceLocation.EXTRA_FOREGROUND_SERVICE_TYPE,
1888                 ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
1889                 | ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE);
1890         final boolean origFgTypePermissionEnforceValue =
1891                 toggleBgFgsTypeStartPermissionEnforcement(false);
1892         try {
1893             // Put Package1 in TOP state, now it gets all capability (because the TOP process
1894             // gets all while-in-use permission (not from FGSL).
1895             CommandReceiver.sendCommand(mContext,
1896                     CommandReceiver.COMMAND_START_ACTIVITY,
1897                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
1898             mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE,
1899                     WatchUidRunner.STATE_TOP,
1900                     new Integer(PROCESS_CAPABILITY_ALL));
1901 
1902             // Start a FGS
1903             CommandReceiver.sendCommand(mContext,
1904                     CommandReceiver.COMMAND_START_FOREGROUND_SERVICE,
1905                     mAppInfo[0].packageName, mAppInfo[0].packageName, 0, bundle);
1906 
1907             // Start a FGSL
1908             bundle.putInt(LocalForegroundServiceLocation.EXTRA_FOREGROUND_SERVICE_TYPE,
1909                     ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION
1910                     | ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
1911                     | ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE);
1912             CommandReceiver.sendCommand(mContext,
1913                     CommandReceiver.COMMAND_START_FOREGROUND_SERVICE_LOCATION,
1914                     mAppInfo[0].packageName, mAppInfo[0].packageName, 0, bundle);
1915 
1916             // Stop the activity.
1917             CommandReceiver.sendCommand(mContext,
1918                     CommandReceiver.COMMAND_STOP_ACTIVITY,
1919                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
1920             // LocalForegroundServiceLocation's forergroundServiceType
1921             // has location|camemra|microphone.
1922             mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE,
1923                     WatchUidRunner.STATE_FG_SERVICE,
1924                     new Integer(PROCESS_CAPABILITY_FOREGROUND_LOCATION
1925                             | PROCESS_CAPABILITY_FOREGROUND_CAMERA
1926                             | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE
1927                             | PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK
1928                             | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK));
1929 
1930             // Bind App 0 -> App 1, verify doesn't include capability.
1931             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1932                     mAppInfo[0].packageName, mAppInfo[1].packageName, 0, null);
1933             // Verify app1 does NOT have capability.
1934             mWatchers[1].waitFor(WatchUidRunner.CMD_PROCSTATE,
1935                     WatchUidRunner.STATE_FG_SERVICE,
1936                     new Integer(PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK
1937                             | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK));
1938 
1939             // Bind App 0 -> App 2, include capability.
1940             bundle = new Bundle();
1941             bundle.putInt(CommandReceiver.EXTRA_FLAGS, Context.BIND_INCLUDE_CAPABILITIES);
1942             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1943                     mAppInfo[0].packageName, mAppInfo[2].packageName, 0, bundle);
1944             // Verify app2 has FOREGROUND_LOCATION capability.
1945             mWatchers[2].waitFor(WatchUidRunner.CMD_PROCSTATE,
1946                     WatchUidRunner.STATE_FG_SERVICE,
1947                     new Integer(PROCESS_CAPABILITY_FOREGROUND_LOCATION
1948                             | PROCESS_CAPABILITY_FOREGROUND_CAMERA
1949                             | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE
1950                             | PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK
1951                             | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK));
1952 
1953             // Back down to foreground service
1954             CommandReceiver.sendCommand(mContext,
1955                     CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE_LOCATION,
1956                     mAppInfo[0].packageName, mAppInfo[0].packageName, 0, null);
1957             // Verify app0 does NOT have FOREGROUND_LOCATION capability.
1958             // LocalForegroundService's forergroundServiceType has camemra|microphone.
1959             mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE,
1960                     WatchUidRunner.STATE_FG_SERVICE,
1961                     new Integer(PROCESS_CAPABILITY_FOREGROUND_CAMERA
1962                             | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE
1963                             | PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK
1964                             | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK));
1965 
1966             // Remove foreground service as well
1967             CommandReceiver.sendCommand(mContext,
1968                     CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE,
1969                     mAppInfo[0].packageName, mAppInfo[0].packageName, 0, null);
1970             mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE,
1971                     WatchUidRunner.STATE_CACHED_EMPTY,
1972                     new Integer(PROCESS_CAPABILITY_NONE));
1973         } finally {
1974             toggleBgFgsTypeStartPermissionEnforcement(origFgTypePermissionEnforceValue);
1975             // Clean up: unbind services to avoid from interferences with other tests
1976             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1977                     mAppInfo[0].packageName, mAppInfo[1].packageName, 0, null);
1978             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1979                     mAppInfo[0].packageName, mAppInfo[2].packageName, 0, null);
1980 
1981             shutdownWatchers();
1982         }
1983     }
1984 
1985     /**
1986      * Test process states for top app binding with and without BIND_INCLUDE_CAPABILITIES flag.
1987      * Bound app should be TOP w/flag and BTOP without flag.
1988      * @throws Exception
1989      */
1990     @Test
testTopBind()1991     public void testTopBind() throws Exception {
1992         setupWatchers(2);
1993 
1994         Activity activity = null;
1995 
1996         try {
1997             // This will start an activity in App0
1998             activity = startSubActivity(ScreenOnActivity.class);
1999 
2000             // Bind Stub -> App 0, verify doesn't include capability (only BTOP, not TOP)
2001             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
2002                     STUB_PACKAGE_NAME, mAppInfo[0].packageName, 0, null);
2003             mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_BOUND_TOP,
2004                     new Integer(PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK
2005                             | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK));
2006 
2007             // Bind Stub -> App 1, include capability (TOP)
2008             Bundle bundle = new Bundle();
2009             bundle.putInt(CommandReceiver.EXTRA_FLAGS, Context.BIND_INCLUDE_CAPABILITIES);
2010             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
2011                     STUB_PACKAGE_NAME, mAppInfo[1].packageName, 0, bundle);
2012             mWatchers[1].waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_BOUND_TOP,
2013                     new Integer(PROCESS_CAPABILITY_ALL));
2014         } finally {
2015             // Clean up: unbind services to avoid from interferences with other tests
2016             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
2017                     STUB_PACKAGE_NAME, mAppInfo[0].packageName, 0, null);
2018             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
2019                     STUB_PACKAGE_NAME, mAppInfo[1].packageName, 0, null);
2020 
2021             shutdownWatchers();
2022             if (activity != null) {
2023                 activity.finish();
2024             }
2025         }
2026     }
2027 
startSubActivity(Class<T> activityClass)2028     private final <T extends Activity> Activity startSubActivity(Class<T> activityClass) {
2029         final Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(
2030                 0, new Intent());
2031         final Instrumentation.ActivityMonitor monitor = new Instrumentation.ActivityMonitor(
2032                 activityClass.getName(), result, false);
2033         mInstrumentation.addMonitor(monitor);
2034         launchActivity(STUB_PACKAGE_NAME, activityClass, null);
2035         return monitor.waitForActivity();
2036     }
2037 
2038     @Test
testCycleTop()2039     public void testCycleTop() throws Exception {
2040         ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo(
2041                 PACKAGE_NAME_APP1, 0);
2042         ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo(
2043                 PACKAGE_NAME_APP2, 0);
2044         ApplicationInfo app3Info = mContext.getPackageManager().getApplicationInfo(
2045                 PACKAGE_NAME_APP3, 0);
2046 
2047         PermissionUtils.grantPermission(
2048                 PACKAGE_NAME_APP1, android.Manifest.permission.PACKAGE_USAGE_STATS);
2049         PermissionUtils.grantPermission(
2050                 PACKAGE_NAME_APP2, android.Manifest.permission.PACKAGE_USAGE_STATS);
2051         PermissionUtils.grantPermission(
2052                 PACKAGE_NAME_APP3, android.Manifest.permission.PACKAGE_USAGE_STATS);
2053 
2054         UidImportanceListener uid1Listener = new UidImportanceListener(mContext,
2055                 app1Info.uid, IMPORTANCE_VISIBLE,
2056                 WAITFOR_MSEC);
2057         uid1Listener.register();
2058 
2059         UidImportanceListener uid1ServiceListener = new UidImportanceListener(mContext,
2060                 app1Info.uid, IMPORTANCE_CACHED,
2061                 WAITFOR_MSEC);
2062         uid1ServiceListener.register();
2063 
2064         UidImportanceListener uid2Listener = new UidImportanceListener(mContext,
2065                 app2Info.uid, IMPORTANCE_VISIBLE,
2066                 WAITFOR_MSEC);
2067         uid2Listener.register();
2068 
2069         UidImportanceListener uid2ServiceListener = new UidImportanceListener(mContext,
2070                 app2Info.uid, IMPORTANCE_CACHED,
2071                 WAITFOR_MSEC);
2072         uid2ServiceListener.register();
2073 
2074         UidImportanceListener uid3Listener = new UidImportanceListener(mContext,
2075                 app3Info.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE,
2076                 WAITFOR_MSEC);
2077         uid3Listener.register();
2078 
2079         UidImportanceListener uid3ServiceListener = new UidImportanceListener(mContext,
2080                 app3Info.uid, IMPORTANCE_CACHED,
2081                 WAITFOR_MSEC);
2082         uid3ServiceListener.register();
2083 
2084         Activity activity = null;
2085 
2086         try {
2087             // Start an activity
2088             activity = startSubActivity(ScreenOnActivity.class);
2089 
2090             SystemUtil.runShellCommand(mInstrumentation,
2091                     "cmd deviceidle whitelist +" + PACKAGE_NAME_APP2);
2092 
2093             // Start a FGS in app2
2094             CommandReceiver.sendCommand(mContext,
2095                     CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, PACKAGE_NAME_APP2,
2096                     PACKAGE_NAME_APP2, 0, null);
2097 
2098             uid2Listener.waitForValue(
2099                     IMPORTANCE_FOREGROUND_SERVICE,
2100                     IMPORTANCE_FOREGROUND_SERVICE);
2101 
2102             // Bind from TOP to the service in app1
2103             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
2104                     STUB_PACKAGE_NAME, PACKAGE_NAME_APP1, 0, null);
2105 
2106             uid1Listener.waitForValue(IMPORTANCE_FOREGROUND,
2107                     IMPORTANCE_FOREGROUND_SERVICE);
2108 
2109             // Bind from app1 to a service in app2
2110             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
2111                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null);
2112 
2113             // Bind from app2 to a service in app3
2114             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
2115                     PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null);
2116 
2117             uid3Listener.waitForValue(IMPORTANCE_FOREGROUND,
2118                     IMPORTANCE_FOREGROUND_SERVICE);
2119 
2120             // Create a cycle
2121             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
2122                     PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null);
2123 
2124             try {
2125                 uid3Listener.waitForValue(IMPORTANCE_CACHED,
2126                         IMPORTANCE_CACHED);
2127                 fail("App3 should not be demoted to cached, expecting FGS");
2128             } catch (IllegalStateException e) {
2129                 // Didn't go to cached in spite of cycle. Good!
2130             }
2131 
2132             // Unbind from the TOP app
2133             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
2134                     STUB_PACKAGE_NAME, PACKAGE_NAME_APP1, 0, null);
2135 
2136             // Check that the apps' proc state is FOREGROUND_SERVICE
2137             uid2Listener.waitForValue(
2138                     IMPORTANCE_FOREGROUND_SERVICE,
2139                     IMPORTANCE_FOREGROUND_SERVICE);
2140 
2141             // Stop the foreground service
2142             CommandReceiver.sendCommand(mContext, CommandReceiver
2143                             .COMMAND_STOP_FOREGROUND_SERVICE,
2144                     PACKAGE_NAME_APP2, PACKAGE_NAME_APP2, 0, null);
2145 
2146             // Check that the apps fall down to cached state
2147             uid1ServiceListener.waitForValue(
2148                     IMPORTANCE_CACHED,
2149                     IMPORTANCE_CACHED);
2150 
2151             uid2ServiceListener.waitForValue(
2152                     IMPORTANCE_CACHED,
2153                     IMPORTANCE_CACHED);
2154 
2155             uid3ServiceListener.waitForValue(
2156                     IMPORTANCE_CACHED,
2157                     IMPORTANCE_CACHED);
2158         } finally {
2159             // Clean up: unbind services to avoid from interferences with other tests
2160             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
2161                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null);
2162             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
2163                     PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null);
2164             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
2165                     PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null);
2166             SystemUtil.runShellCommand(mInstrumentation,
2167                     "cmd deviceidle whitelist -" + PACKAGE_NAME_APP2);
2168 
2169             uid1Listener.unregister();
2170             uid1ServiceListener.unregister();
2171             uid2Listener.unregister();
2172             uid2ServiceListener.unregister();
2173             uid3Listener.unregister();
2174             uid3ServiceListener.unregister();
2175             if (activity != null) {
2176                 activity.finish();
2177             }
2178         }
2179     }
2180 
2181     @Test
testCycleFgAppAndAlert()2182     public void testCycleFgAppAndAlert() throws Exception {
2183         ApplicationInfo stubInfo = mContext.getPackageManager().getApplicationInfo(
2184                 STUB_PACKAGE_NAME, 0);
2185         ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo(
2186                 PACKAGE_NAME_APP1, 0);
2187         ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo(
2188                 PACKAGE_NAME_APP2, 0);
2189         ApplicationInfo app3Info = mContext.getPackageManager().getApplicationInfo(
2190                 PACKAGE_NAME_APP3, 0);
2191 
2192         PermissionUtils.grantPermission(
2193                 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS);
2194         PermissionUtils.grantPermission(
2195                 PACKAGE_NAME_APP1, android.Manifest.permission.PACKAGE_USAGE_STATS);
2196         PermissionUtils.grantPermission(
2197                 PACKAGE_NAME_APP2, android.Manifest.permission.PACKAGE_USAGE_STATS);
2198         PermissionUtils.grantPermission(
2199                 PACKAGE_NAME_APP3, android.Manifest.permission.PACKAGE_USAGE_STATS);
2200 
2201         UidImportanceListener stubListener = new UidImportanceListener(mContext,
2202                 stubInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE,
2203                 WAITFOR_MSEC);
2204         stubListener.register();
2205 
2206         UidImportanceListener uid1Listener = new UidImportanceListener(mContext,
2207                 app1Info.uid, IMPORTANCE_VISIBLE,
2208                 WAITFOR_MSEC);
2209         uid1Listener.register();
2210 
2211         UidImportanceListener uid2Listener = new UidImportanceListener(mContext,
2212                 app2Info.uid, IMPORTANCE_VISIBLE,
2213                 WAITFOR_MSEC);
2214         uid2Listener.register();
2215 
2216         UidImportanceListener uid3Listener = new UidImportanceListener(mContext,
2217                 app3Info.uid, IMPORTANCE_VISIBLE,
2218                 WAITFOR_MSEC);
2219         uid3Listener.register();
2220 
2221         WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid,
2222                 WAITFOR_MSEC);
2223         WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid,
2224                 WAITFOR_MSEC);
2225         WatchUidRunner uid3Watcher = new WatchUidRunner(mInstrumentation, app3Info.uid,
2226                 WAITFOR_MSEC);
2227 
2228         try {
2229             // Stub app should have been in foreground since it's being instrumented.
2230 
2231             PermissionUtils.grantPermission(
2232                     STUB_PACKAGE_NAME, android.Manifest.permission.SYSTEM_ALERT_WINDOW);
2233             // Show an alert on app0
2234             CommandReceiver.sendCommand(mContext,
2235                     CommandReceiver.COMMAND_START_ALERT_SERVICE, STUB_PACKAGE_NAME,
2236                     STUB_PACKAGE_NAME, 0, null);
2237 
2238             SystemUtil.runShellCommand(mInstrumentation,
2239                     "cmd deviceidle whitelist +" + PACKAGE_NAME_APP2);
2240 
2241             // Start a FGS in app2
2242             CommandReceiver.sendCommand(mContext,
2243                     CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, PACKAGE_NAME_APP2,
2244                     PACKAGE_NAME_APP2, 0, null);
2245 
2246             uid2Listener.waitForValue(IMPORTANCE_FOREGROUND_SERVICE,
2247                     IMPORTANCE_FOREGROUND_SERVICE);
2248 
2249             // Bind from app0 to a service in app1
2250             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
2251                     STUB_PACKAGE_NAME, PACKAGE_NAME_APP1, 0, null);
2252 
2253             // Bind from app2 to a service in app1
2254             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
2255                     PACKAGE_NAME_APP2, PACKAGE_NAME_APP1, 0, null);
2256 
2257             // Bind from app3 to a service in app1
2258             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
2259                     PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null);
2260 
2261             // Create a cycle
2262             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
2263                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP3, 0, null);
2264 
2265             uid1Listener.waitForValue(IMPORTANCE_FOREGROUND_SERVICE,
2266                     IMPORTANCE_FOREGROUND_SERVICE);
2267             uid3Listener.waitForValue(IMPORTANCE_FOREGROUND_SERVICE,
2268                     IMPORTANCE_FOREGROUND_SERVICE);
2269 
2270             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
2271                     STUB_PACKAGE_NAME, PACKAGE_NAME_APP1, 0, null);
2272 
2273             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
2274                     PACKAGE_NAME_APP2, PACKAGE_NAME_APP1, 0, null);
2275 
2276             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
2277                     PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null);
2278 
2279             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
2280                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP3, 0, null);
2281 
2282             // Stop the foreground service
2283             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE,
2284                     PACKAGE_NAME_APP2, PACKAGE_NAME_APP2, 0, null);
2285 
2286             // hide the alert
2287             CommandReceiver.sendCommand(mContext,
2288                     CommandReceiver.COMMAND_STOP_ALERT_SERVICE, STUB_PACKAGE_NAME,
2289                     STUB_PACKAGE_NAME, 0, null);
2290 
2291             // Check that the apps' proc state has fallen
2292             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
2293             uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
2294             uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
2295         } finally {
2296             SystemUtil.runShellCommand(mInstrumentation,
2297                     "cmd deviceidle whitelist -" + PACKAGE_NAME_APP2);
2298             stubListener.unregister();
2299             uid1Listener.unregister();
2300             uid2Listener.unregister();
2301             uid3Listener.unregister();
2302             uid1Watcher.finish();
2303             uid2Watcher.finish();
2304             uid3Watcher.finish();
2305         }
2306     }
2307 
2308     /**
2309      * Test FGS compatibility with START_STICKY flag.
2310      * @throws Exception
2311      */
2312     @Test
testFgsSticky1()2313     public void testFgsSticky1() throws Exception {
2314         // For START_STICKY, service is restarted, Service.onStartCommand is called with a null
2315         // intent.
2316         testFgsStickyInternal(Service.START_STICKY, ACTION_RESTART_FGS_STICKY_RESULT,
2317                 (uidWatcher, waiter) -> {
2318                     // After restart, the FGS still has its while-in-use capabilities.
2319                     uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
2320                             WatchUidRunner.STATE_FG_SERVICE,
2321                             new Integer(PROCESS_CAPABILITY_ALL));
2322                     waiter.doWait(WAITFOR_MSEC);
2323                 });
2324     }
2325 
2326     /**
2327      * Test FGS compatibility with START_REDELIVER_INTENT flag.
2328      * @throws Exception
2329      */
2330     @Test
testFgsSticky2()2331     public void testFgsSticky2() throws Exception {
2332         // For START_REDELIVER_INTENT, service is restarted, Service.onStartCommand is called with
2333         // the same intent as previous service start.
2334         testFgsStickyInternal(Service.START_REDELIVER_INTENT, ACTION_START_FGS_RESULT,
2335                 (uidWatcher, waiter) -> {
2336                     // After restart, the FGS still has its while-in-use capabilities.
2337                     uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
2338                             WatchUidRunner.STATE_FG_SERVICE,
2339                             new Integer(PROCESS_CAPABILITY_ALL));
2340                     waiter.doWait(WAITFOR_MSEC);
2341                 });
2342     }
2343 
2344     /**
2345      * Test FGS compatibility with START_NOT_STICKY flag.
2346      * @throws Exception
2347      */
2348     @Test
testFgsSticky3()2349     public void testFgsSticky3() throws Exception {
2350         // For START_NOT_STICKY, service does not restart and Service.onStartCommand is not called
2351         // again.
2352         testFgsStickyInternal(Service.START_NOT_STICKY, ACTION_RESTART_FGS_STICKY_RESULT,
2353                 (uidWatcher, waiter) -> {
2354                     try {
2355                         uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
2356                                 WatchUidRunner.STATE_FG_SERVICE);
2357                         fail("Not-Sticky service should not restart after kill");
2358                     } catch (Exception e) {
2359                     }
2360                     try {
2361                         waiter.doWait(WAITFOR_MSEC);
2362                         fail("Not-Sticky service should not call onStartCommand after kill");
2363                     } catch (Exception e) {
2364                     }
2365                 });
2366 
2367         testFgsStickyInternal(Service.START_NOT_STICKY, ACTION_START_FGS_RESULT,
2368                 (uidWatcher, waiter) -> {
2369                     try {
2370                         uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
2371                                 WatchUidRunner.STATE_FG_SERVICE);
2372                         fail("Not-Sticky service should not restart after kill");
2373                     } catch (Exception e) {
2374                     }
2375                     try {
2376                         waiter.doWait(WAITFOR_MSEC);
2377                         fail("Not-Sticky service should not call onStartCommand after kill");
2378                     } catch (Exception e) {
2379                     }
2380                 });
2381     }
2382 
2383     @Test
testForegroundService_malformedNotificationExtras()2384     public void testForegroundService_malformedNotificationExtras() throws Exception {
2385         PermissionUtils.grantPermission(
2386                 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS);
2387         // Use default timeout value 5000
2388         final ServiceProcessController controller = new ServiceProcessController(mContext,
2389                 mInstrumentation, STUB_PACKAGE_NAME, mAllProcesses);
2390 
2391         ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo(
2392                 SIMPLE_PACKAGE_NAME, 0);
2393         UidImportanceListener uidGoneListener = new UidImportanceListener(mContext,
2394                 appInfo.uid, IMPORTANCE_CACHED, WAIT_TIME);
2395         uidGoneListener.register();
2396 
2397         ActivityManager am = mContext.getSystemService(ActivityManager.class);
2398 
2399         try {
2400             controller.ensureProcessGone();
2401 
2402             // Do initial setup.
2403             controller.makeUidIdle();
2404             controller.removeFromWhitelist();
2405             controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "allow");
2406 
2407             // Put app on whitelist, to allow service to run.
2408             controller.addToWhitelist();
2409 
2410             // Add a bad extra to the FGS notification and try to start the service
2411             // keep key in sync with com.android.cts.launcherapps.simpleapp.SimpleService
2412             mServiceStartForegroundIntent.putExtra("NotifExtras", true);
2413             mContext.startService(mServiceStartForegroundIntent);
2414 
2415             // Make sure we crashed the process
2416             uidGoneListener.waitForValue(IMPORTANCE_GONE, IMPORTANCE_GONE);
2417             assertEquals(IMPORTANCE_GONE, am.getPackageImportance(SIMPLE_PACKAGE_NAME));
2418         } finally {
2419             mContext.stopService(mServiceStartForegroundIntent);
2420             controller.cleanup();
2421             controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "ignore");
2422             controller.removeFromWhitelist();
2423         }
2424     }
2425 
testFgsStickyInternal(int stickyFlag, String waitForBroadcastAction, BiConsumer<WatchUidRunner, WaitForBroadcast> checkKillResult)2426     private void testFgsStickyInternal(int stickyFlag, String waitForBroadcastAction,
2427             BiConsumer<WatchUidRunner, WaitForBroadcast> checkKillResult) throws Exception {
2428         ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo(
2429                 PACKAGE_NAME_APP1, 0);
2430         WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid,
2431                 WAITFOR_MSEC, PROCESS_CAPABILITY_ALL);
2432         AmMonitor monitor = new AmMonitor(mInstrumentation,
2433                 new String[]{AmMonitor.WAIT_FOR_EARLY_ANR, AmMonitor.WAIT_FOR_ANR});
2434         final boolean origFgTypePermissionEnforceValue =
2435                 toggleBgFgsTypeStartPermissionEnforcement(false);
2436         try {
2437             runShellCommand(mInstrumentation, "am service-restart-backoff disable "
2438                     + PACKAGE_NAME_APP1);
2439             // Start an activity in app1 to put app1 in TOP state, so the FGS it started can have
2440             // while-in-use capabilities.
2441             CommandReceiver.sendCommand(mContext,
2442                     CommandReceiver.COMMAND_START_ACTIVITY,
2443                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
2444             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
2445                     WatchUidRunner.STATE_TOP,
2446                     new Integer(PROCESS_CAPABILITY_ALL));
2447 
2448             WaitForBroadcast waiter = new WaitForBroadcast(mInstrumentation.getTargetContext());
2449             waiter.prepare(ACTION_START_FGS_RESULT);
2450             final Bundle extras = new Bundle();
2451             extras.putInt(LocalForegroundServiceLocation.EXTRA_FOREGROUND_SERVICE_TYPE,
2452                     ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION
2453                     | ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
2454                     | ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE);
2455             extras.putInt(LocalForegroundServiceSticky.STICKY_FLAG, stickyFlag);
2456             CommandReceiver.sendCommand(mContext,
2457                     CommandReceiver.COMMAND_START_FOREGROUND_SERVICE_STICKY,
2458                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, extras);
2459 
2460             // Launch home activity, so the activity in app1 will be stopped, app1 now only has FGS,
2461             // we're not "finishing" the activity because removing a task could result in service
2462             // restart.
2463             waitForAppFocus(PACKAGE_NAME_APP1,WAITFOR_MSEC);
2464             final Intent homeIntent = new Intent();
2465             homeIntent.setAction(Intent.ACTION_MAIN);
2466             homeIntent.addCategory(Intent.CATEGORY_HOME);
2467             homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2468             mTargetContext.startActivity(homeIntent);
2469 
2470             // The FGS has all while-in-use capabilities.
2471             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE,
2472                     new Integer(PROCESS_CAPABILITY_ALL));
2473             waiter.doWait(WAITFOR_MSEC);
2474 
2475             waiter = new WaitForBroadcast(mInstrumentation.getTargetContext());
2476             waiter.prepare(waitForBroadcastAction);
2477             CtsAppTestUtils.executeShellCmd(mInstrumentation,
2478                     "am crash " + PACKAGE_NAME_APP1);
2479             monitor.waitFor(AmMonitor.WAIT_FOR_CRASHED, WAITFOR_MSEC);
2480             monitor.sendCommand(AmMonitor.CMD_KILL);
2481             checkKillResult.accept(uid1Watcher, waiter);
2482         } finally {
2483             runShellCommand(mInstrumentation, "am service-restart-backoff enable "
2484                     + PACKAGE_NAME_APP1);
2485             toggleBgFgsTypeStartPermissionEnforcement(origFgTypePermissionEnforceValue);
2486             final ActivityManager am = mContext.getSystemService(ActivityManager.class);
2487             SystemUtil.runWithShellPermissionIdentity(() -> {
2488                 am.forceStopPackage(PACKAGE_NAME_APP1);
2489             });
2490             uid1Watcher.finish();
2491             monitor.finish();
2492         }
2493     }
2494 
2495     /**
2496      * Test that process in foreground service state does not get an implicit capability except
2497      * network.
2498      * @throws Exception
2499      */
2500     @Test
testFgsDefaultCapabilityNone()2501     public void testFgsDefaultCapabilityNone() throws Exception {
2502         setupWatchers(2);
2503 
2504         final Bundle bundle = new Bundle();
2505         bundle.putInt(LocalForegroundServiceLocation.EXTRA_FOREGROUND_SERVICE_TYPE,
2506                 ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
2507                 | ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE);
2508         final boolean origFgTypePermissionEnforceValue =
2509                 toggleBgFgsTypeStartPermissionEnforcement(false);
2510 
2511         try {
2512             // Put Package1 in TOP state.
2513             CommandReceiver.sendCommand(mContext,
2514                     CommandReceiver.COMMAND_START_ACTIVITY,
2515                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
2516             mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE,
2517                     WatchUidRunner.STATE_TOP,
2518                     new Integer(PROCESS_CAPABILITY_ALL));
2519 
2520             // Start a FGS from TOP state.
2521             CommandReceiver.sendCommand(mContext,
2522                     CommandReceiver.COMMAND_START_FOREGROUND_SERVICE,
2523                     mAppInfo[0].packageName, mAppInfo[0].packageName, 0, bundle);
2524 
2525             // Stop the activity.
2526             CommandReceiver.sendCommand(mContext,
2527                     CommandReceiver.COMMAND_STOP_ACTIVITY,
2528                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
2529             // LocalForegroundService's forergroundServiceType has camemra|microphone.
2530             mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE,
2531                     WatchUidRunner.STATE_FG_SERVICE,
2532                     new Integer(PROCESS_CAPABILITY_FOREGROUND_CAMERA
2533                             | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE
2534                             | PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK
2535                             | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK));
2536 
2537             // Bind App 0 -> App 1.
2538             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
2539                     mAppInfo[0].packageName, mAppInfo[1].packageName, 0, null);
2540             // App1 is in foreground service state, app1 does NOT have implicit capability
2541             // except network.
2542             mWatchers[1].waitFor(WatchUidRunner.CMD_PROCSTATE,
2543                     WatchUidRunner.STATE_FG_SERVICE,
2544                     new Integer(PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK
2545                             | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK));
2546 
2547             // Stop App 0's foreground service.
2548             CommandReceiver.sendCommand(mContext,
2549                     CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE,
2550                     mAppInfo[0].packageName, mAppInfo[0].packageName, 0, null);
2551             mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE,
2552                     WatchUidRunner.STATE_CACHED_EMPTY,
2553                     new Integer(PROCESS_CAPABILITY_NONE));
2554         } finally {
2555             toggleBgFgsTypeStartPermissionEnforcement(origFgTypePermissionEnforceValue);
2556             // Clean up: unbind services to avoid from interferences with other tests
2557             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
2558                     mAppInfo[0].packageName, mAppInfo[1].packageName, 0, null);
2559             shutdownWatchers();
2560         }
2561     }
2562 
2563     @Test
testProcessDeathBindings()2564     public void testProcessDeathBindings() throws Exception {
2565         ApplicationInfo clientAppInfo = mContext.getPackageManager().getApplicationInfo(
2566                 PACKAGE_NAME_APP1, 0);
2567         WatchUidRunner clientWatcher = new WatchUidRunner(mInstrumentation, clientAppInfo.uid,
2568                 WAITFOR_MSEC, PROCESS_CAPABILITY_ALL);
2569 
2570         ApplicationInfo serviceAppInfo = mContext.getPackageManager().getApplicationInfo(
2571                 PACKAGE_NAME_APP2, 0);
2572         WatchUidRunner serviceWatcher = new WatchUidRunner(mInstrumentation, serviceAppInfo.uid,
2573                 WAITFOR_MSEC, PROCESS_CAPABILITY_ALL);
2574 
2575         ApplicationInfo providerAppInfo = mContext.getPackageManager().getApplicationInfo(
2576                 PACKAGE_NAME_PROVIDER_APP, 0);
2577         WatchUidRunner providerWatcher = new WatchUidRunner(mInstrumentation, providerAppInfo.uid,
2578                 WAITFOR_MSEC, PROCESS_CAPABILITY_ALL);
2579         final Uri testProviderUri = new Uri.Builder()
2580                 .scheme(SCHEME_CONTENT)
2581                 .authority(TestProvider.AUTHORITY)
2582                 .build();
2583         final Bundle providerUriBundle = new Bundle();
2584         providerUriBundle.putParcelable(CommandReceiver.EXTRA_URI, testProviderUri);
2585 
2586         try {
2587             // Bring client app to TOP by starting an activity.
2588             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_START_ACTIVITY,
2589                     clientAppInfo.packageName, clientAppInfo.packageName, 0, null);
2590             clientWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP);
2591 
2592             // Bind client to service
2593             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
2594                     clientAppInfo.packageName, serviceAppInfo.packageName, 0, null);
2595             serviceWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_BOUND_TOP);
2596 
2597             // Bind client to provider
2598             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_ACQUIRE_CONTENT_PROVIDER,
2599                     clientAppInfo.packageName, clientAppInfo.packageName, 0, providerUriBundle);
2600             providerWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_BOUND_TOP);
2601 
2602             // Crash client
2603             CtsAppTestUtils.executeShellCmd(mInstrumentation,
2604                     "am crash " + clientAppInfo.packageName);
2605             serviceWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
2606             providerWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
2607                     WatchUidRunner.STATE_CACHED_EMPTY);
2608 
2609         } finally {
2610             // Clean up: unbind services to avoid from interferences with other tests
2611             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_STOP_ACTIVITY,
2612                     clientAppInfo.packageName, clientAppInfo.packageName, 0, null);
2613             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
2614                     clientAppInfo.packageName, serviceAppInfo.packageName, 0, null);
2615             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_RELEASE_CONTENT_PROVIDER,
2616                     clientAppInfo.packageName, clientAppInfo.packageName, 0, providerUriBundle);
2617 
2618             clientWatcher.finish();
2619             serviceWatcher.finish();
2620             providerWatcher.finish();
2621         }
2622     }
2623 
2624     @Test
testProcessDeathBindings_anotherClient()2625     public void testProcessDeathBindings_anotherClient() throws Exception {
2626         ApplicationInfo clientAppInfo = mContext.getPackageManager().getApplicationInfo(
2627                 PACKAGE_NAME_APP1, 0);
2628         WatchUidRunner clientWatcher = new WatchUidRunner(mInstrumentation, clientAppInfo.uid,
2629                 WAITFOR_MSEC, PROCESS_CAPABILITY_ALL);
2630 
2631         ApplicationInfo serviceAppInfo = mContext.getPackageManager().getApplicationInfo(
2632                 PACKAGE_NAME_APP2, 0);
2633         WatchUidRunner serviceWatcher = new WatchUidRunner(mInstrumentation, serviceAppInfo.uid,
2634                 WAITFOR_MSEC, PROCESS_CAPABILITY_ALL);
2635 
2636         ApplicationInfo providerAppInfo = mContext.getPackageManager().getApplicationInfo(
2637                 PACKAGE_NAME_PROVIDER_APP, 0);
2638         WatchUidRunner providerWatcher = new WatchUidRunner(mInstrumentation, providerAppInfo.uid,
2639                 WAITFOR_MSEC, PROCESS_CAPABILITY_ALL);
2640         final Uri testProviderUri = new Uri.Builder()
2641                 .scheme(SCHEME_CONTENT)
2642                 .authority(TestProvider.AUTHORITY)
2643                 .build();
2644         final Bundle providerUriBundle = new Bundle();
2645         providerUriBundle.putParcelable(CommandReceiver.EXTRA_URI, testProviderUri);
2646 
2647         try {
2648             // Start a FGS and bind to service and provider.
2649             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_START_FOREGROUND_SERVICE,
2650                     STUB_PACKAGE_NAME, STUB_PACKAGE_NAME, 0, null);
2651             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
2652                     STUB_PACKAGE_NAME, serviceAppInfo.packageName, 0, null);
2653             serviceWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
2654             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_ACQUIRE_CONTENT_PROVIDER,
2655                     STUB_PACKAGE_NAME, STUB_PACKAGE_NAME, 0, providerUriBundle);
2656             providerWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
2657                     WatchUidRunner.STATE_BOUND_FG_SERVICE);
2658 
2659             // Bring client app to TOP by starting an activity.
2660             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_START_ACTIVITY,
2661                     clientAppInfo.packageName, clientAppInfo.packageName, 0, null);
2662             clientWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP);
2663 
2664             // Bind client to service
2665             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
2666                     clientAppInfo.packageName, serviceAppInfo.packageName, 0, null);
2667             serviceWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_BOUND_TOP);
2668 
2669             // Bind client to provider
2670             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_ACQUIRE_CONTENT_PROVIDER,
2671                     clientAppInfo.packageName, clientAppInfo.packageName, 0, providerUriBundle);
2672             providerWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_BOUND_TOP);
2673 
2674             // Crash client
2675             CtsAppTestUtils.executeShellCmd(mInstrumentation,
2676                     "am crash " + clientAppInfo.packageName);
2677             serviceWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
2678             providerWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
2679                     WatchUidRunner.STATE_BOUND_FG_SERVICE);
2680 
2681         } finally {
2682             // Clean up: unbind services to avoid from interferences with other tests
2683             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE,
2684                     STUB_PACKAGE_NAME, STUB_PACKAGE_NAME, 0, null);
2685             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
2686                     STUB_PACKAGE_NAME, serviceAppInfo.packageName, 0, null);
2687             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_RELEASE_CONTENT_PROVIDER,
2688                     STUB_PACKAGE_NAME, STUB_PACKAGE_NAME, 0, providerUriBundle);
2689             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_STOP_ACTIVITY,
2690                     clientAppInfo.packageName, clientAppInfo.packageName, 0, null);
2691             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
2692                     clientAppInfo.packageName, serviceAppInfo.packageName, 0, null);
2693             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_RELEASE_CONTENT_PROVIDER,
2694                     clientAppInfo.packageName, clientAppInfo.packageName, 0, providerUriBundle);
2695 
2696             clientWatcher.finish();
2697             serviceWatcher.finish();
2698             providerWatcher.finish();
2699         }
2700     }
2701 
2702     // Copied from android.test.InstrumentationTestCase
2703     /**
2704      * Utility method for launching an activity.
2705      *
2706      * <p>The {@link Intent} used to launch the Activity is:
2707      *  action = {@link Intent#ACTION_MAIN}
2708      *  extras = null, unless a custom bundle is provided here
2709      * All other fields are null or empty.
2710      *
2711      * <p><b>NOTE:</b> The parameter <i>pkg</i> must refer to the package identifier of the
2712      * package hosting the activity to be launched, which is specified in the AndroidManifest.xml
2713      * file.  This is not necessarily the same as the java package name.
2714      *
2715      * @param pkg The package hosting the activity to be launched.
2716      * @param activityCls The activity class to launch.
2717      * @param extras Optional extra stuff to pass to the activity.
2718      * @return The activity, or null if non launched.
2719      */
launchActivity( String pkg, Class<T> activityCls, Bundle extras)2720     public final <T extends Activity> T launchActivity(
2721             String pkg,
2722             Class<T> activityCls,
2723             Bundle extras) {
2724         Intent intent = new Intent(Intent.ACTION_MAIN);
2725         if (extras != null) {
2726             intent.putExtras(extras);
2727         }
2728         return launchActivityWithIntent(pkg, activityCls, intent);
2729     }
2730 
2731     // Copied from android.test.InstrumentationTestCase
2732     /**
2733      * Utility method for launching an activity with a specific Intent.
2734      *
2735      * <p><b>NOTE:</b> The parameter <i>pkg</i> must refer to the package identifier of the
2736      * package hosting the activity to be launched, which is specified in the AndroidManifest.xml
2737      * file.  This is not necessarily the same as the java package name.
2738      *
2739      * @param pkg The package hosting the activity to be launched.
2740      * @param activityCls The activity class to launch.
2741      * @param intent The intent to launch with
2742      * @return The activity, or null if non launched.
2743      */
2744     @SuppressWarnings("unchecked")
launchActivityWithIntent( String pkg, Class<T> activityCls, Intent intent)2745     public final <T extends Activity> T launchActivityWithIntent(
2746             String pkg,
2747             Class<T> activityCls,
2748             Intent intent) {
2749         intent.setClassName(pkg, activityCls.getName());
2750         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2751         T activity = (T) mInstrumentation.startActivitySync(intent);
2752         mInstrumentation.waitForIdleSync();
2753         return activity;
2754     }
2755 }
2756