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