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