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.RunningAppProcessInfo.IMPORTANCE_CACHED;
20 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
21 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE;
22 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
23 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
24 
25 import android.accessibilityservice.AccessibilityService;
26 import android.app.Activity;
27 import android.app.ActivityManager;
28 import android.app.AppOpsManager;
29 import android.app.Instrumentation;
30 import android.app.KeyguardManager;
31 import android.app.cts.android.app.cts.tools.ServiceConnectionHandler;
32 import android.app.cts.android.app.cts.tools.ServiceProcessController;
33 import android.app.cts.android.app.cts.tools.SyncOrderedBroadcast;
34 import android.app.cts.android.app.cts.tools.UidImportanceListener;
35 import android.app.cts.android.app.cts.tools.WaitForBroadcast;
36 import android.app.cts.android.app.cts.tools.WatchUidRunner;
37 import android.app.stubs.CommandReceiver;
38 import android.app.stubs.LocalForegroundServiceLocation;
39 import android.app.stubs.ScreenOnActivity;
40 import android.content.ComponentName;
41 import android.content.Context;
42 import android.content.Intent;
43 import android.content.pm.ApplicationInfo;
44 import android.content.pm.PackageManager;
45 import android.content.pm.ServiceInfo;
46 import android.content.res.Configuration;
47 import android.os.Build;
48 import android.os.Bundle;
49 import android.os.IBinder;
50 import android.os.Parcel;
51 import android.os.PowerManager;
52 import android.os.RemoteException;
53 import android.os.SystemClock;
54 import android.server.wm.WindowManagerState;
55 import android.support.test.uiautomator.BySelector;
56 import android.support.test.uiautomator.UiDevice;
57 import android.support.test.uiautomator.UiSelector;
58 import android.test.InstrumentationTestCase;
59 import android.util.Log;
60 import android.view.accessibility.AccessibilityEvent;
61 
62 import androidx.test.InstrumentationRegistry;
63 
64 import com.android.compatibility.common.util.CommonTestUtils;
65 import com.android.compatibility.common.util.SystemUtil;
66 
67 public class ActivityManagerProcessStateTest extends InstrumentationTestCase {
68     private static final String TAG = ActivityManagerProcessStateTest.class.getName();
69 
70     private static final String STUB_PACKAGE_NAME = "android.app.stubs";
71     private static final String PACKAGE_NAME_APP1 = "com.android.app1";
72     private static final String PACKAGE_NAME_APP2 = "com.android.app2";
73     private static final String PACKAGE_NAME_APP3 = "com.android.app3";
74 
75     private static final String[] PACKAGE_NAMES = {
76         PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, PACKAGE_NAME_APP3
77     };
78 
79     private static final int WAIT_TIME = 10000;
80     private static final int WAITFOR_MSEC = 10000;
81     // A secondary test activity from another APK.
82     static final String SIMPLE_PACKAGE_NAME = "com.android.cts.launcherapps.simpleapp";
83     static final String SIMPLE_SERVICE = ".SimpleService";
84     static final String SIMPLE_SERVICE2 = ".SimpleService2";
85     static final String SIMPLE_SERVICE3 = ".SimpleService3";
86     static final String SIMPLE_RECEIVER_START_SERVICE = ".SimpleReceiverStartService";
87     static final String SIMPLE_ACTIVITY_START_SERVICE = ".SimpleActivityStartService";
88     static final String SIMPLE_ACTIVITY_START_FG_SERVICE = ".SimpleActivityStartFgService";
89     public static String ACTION_SIMPLE_ACTIVITY_START_SERVICE_RESULT =
90             "com.android.cts.launcherapps.simpleapp.SimpleActivityStartService.RESULT";
91     static final String ACTION_SIMPLE_ACTIVITY_START_FG =
92             "com.android.cts.launcherapps.simpleapp.SimpleActivityStartFgService.START_THEN_FG";
93     public static String ACTION_SIMPLE_ACTIVITY_START_FG_SERVICE_RESULT =
94             "com.android.cts.launcherapps.simpleapp.SimpleActivityStartFgService.NOW_FOREGROUND";
95     public static String ACTION_FINISH_EVERYTHING =
96             "com.android.cts.launcherapps.simpleapp.SimpleActivityStartFgService.FINISH_ALL";
97 
98     // APKs for testing heavy weight app interactions.
99     static final String CANT_SAVE_STATE_1_PACKAGE_NAME = "com.android.test.cantsavestate1";
100     static final String CANT_SAVE_STATE_2_PACKAGE_NAME = "com.android.test.cantsavestate2";
101 
102     // Actions
103     static final String ACTION_START_FOREGROUND = "com.android.test.action.START_FOREGROUND";
104     static final String ACTION_STOP_FOREGROUND = "com.android.test.action.STOP_FOREGROUND";
105     static final String ACTION_START_THEN_FG = "com.android.test.action.START_THEN_FG";
106     static final String ACTION_STOP_SERVICE = "com.android.test.action.STOP";
107 
108     private static final int TEMP_WHITELIST_DURATION_MS = 2000;
109 
110     private Context mContext;
111     private Instrumentation mInstrumentation;
112     private Intent mServiceIntent;
113     private Intent mServiceStartForegroundIntent;
114     private Intent mServiceStopForegroundIntent;
115     private Intent mService2Intent;
116     private Intent mService3Intent;
117     private Intent mServiceStartForeground3Intent;
118     private Intent mMainProcess[];
119     private Intent mAllProcesses[];
120 
121     private int mAppCount;
122     private ApplicationInfo [] mAppInfo;
123     private WatchUidRunner [] mWatchers;
124 
125 
126     @Override
setUp()127     protected void setUp() throws Exception {
128         super.setUp();
129         mInstrumentation = getInstrumentation();
130         mContext = mInstrumentation.getContext();
131         mServiceIntent = new Intent();
132         mServiceIntent.setClassName(SIMPLE_PACKAGE_NAME, SIMPLE_PACKAGE_NAME + SIMPLE_SERVICE);
133         mServiceStartForegroundIntent = new Intent(mServiceIntent);
134         mServiceStartForegroundIntent.setAction(ACTION_START_FOREGROUND);
135         mServiceStopForegroundIntent = new Intent(mServiceIntent);
136         mServiceStopForegroundIntent.setAction(ACTION_STOP_FOREGROUND);
137         mService2Intent = new Intent()
138                 .setClassName(SIMPLE_PACKAGE_NAME, SIMPLE_PACKAGE_NAME + SIMPLE_SERVICE2);
139         mService3Intent = new Intent()
140                 .setClassName(SIMPLE_PACKAGE_NAME, SIMPLE_PACKAGE_NAME + SIMPLE_SERVICE3);
141         mMainProcess = new Intent[1];
142         mMainProcess[0] = mServiceIntent;
143         mAllProcesses = new Intent[2];
144         mAllProcesses[0] = mServiceIntent;
145         mAllProcesses[1] = mService2Intent;
146         mContext.stopService(mServiceIntent);
147         mContext.stopService(mService2Intent);
148         mContext.stopService(mService3Intent);
149         turnScreenOn();
150         removeTestAppFromWhitelists();
151         mAppCount = 0;
152     }
153 
154     /** Set up count app info objects and WatchUidRunners. */
setupWatchers(int count)155     private void setupWatchers(int count) throws Exception {
156         mAppCount = count;
157         mAppInfo = new ApplicationInfo[count];
158         mWatchers = new WatchUidRunner[count];
159         for (int i = 0; i < count; i++) {
160             mAppInfo[i] = mContext.getPackageManager().getApplicationInfo(
161                     PACKAGE_NAMES[i], 0);
162             mWatchers[i] = new WatchUidRunner(mInstrumentation, mAppInfo[i].uid,
163                     WAITFOR_MSEC);
164         }
165     }
166 
167     /** Finish all started WatchUidRunners. */
shutdownWatchers()168     private void shutdownWatchers() throws Exception {
169         for (int i = 0; i < mAppCount; i++) {
170             mWatchers[i].finish();
171         }
172     }
173 
turnScreenOn()174     private void turnScreenOn() throws Exception {
175         executeShellCmd("input keyevent KEYCODE_WAKEUP");
176         executeShellCmd("wm dismiss-keyguard");
177         /*
178         Wait until the screen becomes interactive to start the test cases.
179         Otherwise the procstat may start in TOP_SLEEPING state, and this
180         causes test case testBackgroundCheckActivityService to fail.
181         Note: There could still a small chance the procstat is TOP_SLEEPING
182         when the predicate returns true.
183         */
184         CommonTestUtils.waitUntil("Device does not wake up after 5 seconds",
185             5,
186             () ->  {
187                 return isScreenInteractive() && !isKeyguardLocked();
188             });
189     }
190 
removeTestAppFromWhitelists()191     private void removeTestAppFromWhitelists() throws Exception {
192         executeShellCmd("cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME);
193         executeShellCmd("cmd deviceidle tempwhitelist -r " + SIMPLE_PACKAGE_NAME);
194     }
195 
executeShellCmd(String cmd)196     private String executeShellCmd(String cmd) throws Exception {
197         final String result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
198         Log.d(TAG, String.format("Output for '%s': %s", cmd, result));
199         return result;
200     }
201 
isScreenInteractive()202     private boolean isScreenInteractive() {
203         final PowerManager powerManager =
204                 (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
205         return powerManager.isInteractive();
206     }
207 
isKeyguardLocked()208     private boolean isKeyguardLocked() {
209         final KeyguardManager keyguardManager =
210                 (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
211         return keyguardManager.isKeyguardLocked();
212     }
213 
waitForAppFocus(String waitForApp, long waitTime)214     private void waitForAppFocus(String waitForApp, long waitTime) {
215         long waitUntil = SystemClock.elapsedRealtime() + waitTime;
216         while (true) {
217             WindowManagerState wms = new WindowManagerState();
218             wms.computeState();
219             String appName = wms.getFocusedApp();
220             if (appName != null) {
221                 ComponentName comp = ComponentName.unflattenFromString(appName);
222                 if (waitForApp.equals(comp.getPackageName())) {
223                     break;
224                 }
225             }
226             if (SystemClock.elapsedRealtime() > waitUntil) {
227                 throw new IllegalStateException("Timed out waiting for focus on app "
228                         + waitForApp + ", last was " + appName);
229             }
230             Log.i(TAG, "Waiting for app focus, current: " + appName);
231             try {
232                 Thread.sleep(100);
233             } catch (InterruptedException e) {
234             }
235         };
236     }
237 
startActivityAndWaitForShow(final Intent intent)238     private void startActivityAndWaitForShow(final Intent intent) throws Exception {
239         getInstrumentation().getUiAutomation().executeAndWaitForEvent(
240                 () -> {
241                     try {
242                         mContext.startActivity(intent);
243                     } catch (Exception e) {
244                         fail("Cannot start activity: " + intent);
245                     }
246                 }, (AccessibilityEvent event) -> event.getEventType()
247                         == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
248                 , WAIT_TIME);
249     }
250 
maybeClick(UiDevice device, UiSelector sel)251     private void maybeClick(UiDevice device, UiSelector sel) {
252         try { device.findObject(sel).click(); } catch (Throwable ignored) { }
253     }
254 
maybeClick(UiDevice device, BySelector sel)255     private void maybeClick(UiDevice device, BySelector sel) {
256         try { device.findObject(sel).click(); } catch (Throwable ignored) { }
257     }
258 
259     /**
260      * Test basic state changes as processes go up and down due to services running in them.
261      */
testUidImportanceListener()262     public void testUidImportanceListener() throws Exception {
263         final Parcel data = Parcel.obtain();
264         ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext, mServiceIntent,
265                 WAIT_TIME);
266         ServiceConnectionHandler conn2 = new ServiceConnectionHandler(mContext, mService2Intent,
267                 WAIT_TIME);
268 
269         ActivityManager am = mContext.getSystemService(ActivityManager.class);
270 
271         ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo(
272                 SIMPLE_PACKAGE_NAME, 0);
273         UidImportanceListener uidForegroundListener = new UidImportanceListener(mContext,
274                 appInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE, WAIT_TIME);
275 
276         InstrumentationRegistry.getInstrumentation().getUiAutomation().revokeRuntimePermission(
277                 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS);
278         boolean gotException = false;
279         try {
280             uidForegroundListener.register();
281         } catch (SecurityException e) {
282             gotException = true;
283         }
284         assertTrue("Expected SecurityException thrown", gotException);
285 
286         InstrumentationRegistry.getInstrumentation().getUiAutomation().grantRuntimePermission(
287                 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS);
288         /*
289         Log.d("XXXX", "Invoke: " + cmd);
290         Log.d("XXXX", "Result: " + result);
291         Log.d("XXXX", SystemUtil.runShellCommand(getInstrumentation(), "dumpsys package "
292                 + STUB_PACKAGE_NAME));
293         */
294         uidForegroundListener.register();
295 
296         UidImportanceListener uidGoneListener = new UidImportanceListener(mContext,
297                 appInfo.uid, IMPORTANCE_CACHED, WAIT_TIME);
298         uidGoneListener.register();
299 
300         WatchUidRunner uidWatcher = new WatchUidRunner(getInstrumentation(), appInfo.uid,
301                 WAIT_TIME);
302 
303         try {
304             // First kill the processes to start out in a stable state.
305             conn.bind();
306             conn2.bind();
307             IBinder service1 = conn.getServiceIBinder();
308             IBinder service2 = conn2.getServiceIBinder();
309             conn.unbind();
310             conn2.unbind();
311             try {
312                 service1.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0);
313             } catch (RemoteException e) {
314             }
315             try {
316                 service2.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0);
317             } catch (RemoteException e) {
318             }
319             service1 = service2 = null;
320 
321             // Wait for uid's processes to go away.
322             uidGoneListener.waitForValue(IMPORTANCE_GONE, IMPORTANCE_GONE);
323             assertEquals(IMPORTANCE_GONE, am.getPackageImportance(SIMPLE_PACKAGE_NAME));
324 
325             // And wait for the uid report to be gone.
326             uidWatcher.waitFor(WatchUidRunner.CMD_GONE, null);
327 
328             // Now bind and see if we get told about the uid coming in to the foreground.
329             conn.bind();
330             uidForegroundListener.waitForValue(IMPORTANCE_FOREGROUND, IMPORTANCE_VISIBLE);
331             assertEquals(IMPORTANCE_FOREGROUND_SERVICE,
332                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
333 
334             // Also make sure the uid state reports are as expected.  Wait for active because
335             // there may be some intermediate states as the process comes up.
336             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
337             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
338             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
339 
340             // Pull out the service IBinder for a kludy hack...
341             IBinder service = conn.getServiceIBinder();
342 
343             // Now unbind and see if we get told about it going to the background.
344             conn.unbind();
345             uidForegroundListener.waitForValue(IMPORTANCE_CACHED, IMPORTANCE_CACHED);
346             assertEquals(IMPORTANCE_CACHED, am.getPackageImportance(SIMPLE_PACKAGE_NAME));
347 
348             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null);
349             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
350 
351             // Now kill the process and see if we are told about it being gone.
352             try {
353                 service.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0);
354             } catch (RemoteException e) {
355                 // It is okay if it is already gone for some reason.
356             }
357 
358             uidGoneListener.waitForValue(IMPORTANCE_GONE, IMPORTANCE_GONE);
359             assertEquals(IMPORTANCE_GONE, am.getPackageImportance(SIMPLE_PACKAGE_NAME));
360 
361             uidWatcher.expect(WatchUidRunner.CMD_IDLE, null);
362             uidWatcher.expect(WatchUidRunner.CMD_GONE, null);
363 
364             // Now we are going to try different combinations of binding to two processes to
365             // see if they are correctly combined together for the app.
366 
367             // Bring up both services.
368             conn.bind();
369             conn2.bind();
370             uidForegroundListener.waitForValue(IMPORTANCE_FOREGROUND, IMPORTANCE_VISIBLE);
371             assertEquals(IMPORTANCE_FOREGROUND_SERVICE,
372                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
373 
374             // Also make sure the uid state reports are as expected.
375             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
376             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
377             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
378 
379             // Bring down one service, app state should remain foreground.
380             conn2.unbind();
381             assertEquals(IMPORTANCE_FOREGROUND_SERVICE,
382                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
383 
384             // Bring down other service, app state should now be cached.  (If the processes both
385             // actually get killed immediately, this is also not a correctly behaving system.)
386             conn.unbind();
387             uidGoneListener.waitForValue(IMPORTANCE_CACHED, IMPORTANCE_CACHED);
388             assertEquals(IMPORTANCE_CACHED,
389                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
390 
391             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null);
392             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
393 
394             // Bring up one service, this should be sufficient to become foreground.
395             conn2.bind();
396             uidForegroundListener.waitForValue(IMPORTANCE_FOREGROUND, IMPORTANCE_VISIBLE);
397             assertEquals(IMPORTANCE_FOREGROUND_SERVICE,
398                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
399 
400             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
401             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
402 
403             // Bring up other service, should remain foreground.
404             conn.bind();
405             assertEquals(IMPORTANCE_FOREGROUND_SERVICE,
406                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
407 
408             // Bring down one service, should remain foreground.
409             conn.unbind();
410             assertEquals(IMPORTANCE_FOREGROUND_SERVICE,
411                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
412 
413             // And bringing down other service should put us back to cached.
414             conn2.unbind();
415             uidGoneListener.waitForValue(IMPORTANCE_CACHED,
416                     IMPORTANCE_CACHED);
417             assertEquals(IMPORTANCE_CACHED,
418                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
419 
420             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null);
421             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
422         } finally {
423             data.recycle();
424             uidWatcher.finish();
425             uidForegroundListener.unregister();
426             uidGoneListener.unregister();
427         }
428     }
429 
430     /**
431      * Test that background check correctly prevents idle services from running but allows
432      * whitelisted apps to bypass the check.
433      */
testBackgroundCheckService()434     public void testBackgroundCheckService() throws Exception {
435         final Parcel data = Parcel.obtain();
436         Intent serviceIntent = new Intent();
437         serviceIntent.setClassName(SIMPLE_PACKAGE_NAME,
438                 SIMPLE_PACKAGE_NAME + SIMPLE_SERVICE);
439         ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext, serviceIntent,
440                 WAIT_TIME);
441 
442         ActivityManager am = mContext.getSystemService(ActivityManager.class);
443 
444         InstrumentationRegistry.getInstrumentation().getUiAutomation().grantRuntimePermission(
445                 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS);
446         /*
447         Log.d("XXXX", "Invoke: " + cmd);
448         Log.d("XXXX", "Result: " + result);
449         Log.d("XXXX", SystemUtil.runShellCommand(getInstrumentation(), "dumpsys package "
450                 + STUB_PACKAGE_NAME));
451         */
452 
453         ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo(
454                 SIMPLE_PACKAGE_NAME, 0);
455 
456         UidImportanceListener uidForegroundListener = new UidImportanceListener(mContext,
457                 appInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE, WAIT_TIME);
458         uidForegroundListener.register();
459         UidImportanceListener uidGoneListener = new UidImportanceListener(mContext,
460                 appInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY, WAIT_TIME);
461         uidGoneListener.register();
462 
463         WatchUidRunner uidWatcher = new WatchUidRunner(getInstrumentation(), appInfo.uid,
464                 WAIT_TIME);
465 
466         // First kill the process to start out in a stable state.
467         mContext.stopService(serviceIntent);
468         conn.bind();
469         IBinder service = conn.getServiceIBinder();
470         conn.unbind();
471         try {
472             service.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0);
473         } catch (RemoteException e) {
474         }
475         service = null;
476 
477         // Wait for uid's process to go away.
478         uidGoneListener.waitForValue(IMPORTANCE_GONE, IMPORTANCE_GONE);
479         assertEquals(IMPORTANCE_GONE,
480                 am.getPackageImportance(SIMPLE_PACKAGE_NAME));
481 
482         // And wait for the uid report to be gone.
483         uidWatcher.waitFor(WatchUidRunner.CMD_GONE, null);
484 
485         String cmd = "appops set " + SIMPLE_PACKAGE_NAME + " RUN_IN_BACKGROUND deny";
486         String result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
487 
488         // This is a side-effect of the app op command.
489         uidWatcher.expect(WatchUidRunner.CMD_IDLE, null);
490         uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "NONE");
491 
492         // We don't want to wait for the uid to actually go idle, we can force it now.
493         cmd = "am make-uid-idle " + SIMPLE_PACKAGE_NAME;
494         result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
495 
496         // Make sure app is not yet on whitelist
497         cmd = "cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME;
498         result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
499 
500         // We will use this to monitor when the service is running.
501         conn.startMonitoring();
502 
503         try {
504             // Try starting the service.  Should fail!
505             boolean failed = false;
506             try {
507                 mContext.startService(serviceIntent);
508             } catch (IllegalStateException e) {
509                 failed = true;
510             }
511             if (!failed) {
512                 fail("Service was allowed to start while in the background");
513             }
514 
515             // Put app on temporary whitelist to see if this allows the service start.
516             cmd = String.format("cmd deviceidle tempwhitelist -d %d %s",
517                     TEMP_WHITELIST_DURATION_MS, SIMPLE_PACKAGE_NAME);
518             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
519 
520             // Try starting the service now that the app is whitelisted...  should work!
521             mContext.startService(serviceIntent);
522             conn.waitForConnect();
523 
524             // Also make sure the uid state reports are as expected.
525             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
526             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
527             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
528 
529             // Good, now stop the service and give enough time to get off the temp whitelist.
530             mContext.stopService(serviceIntent);
531             conn.waitForDisconnect();
532 
533             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
534             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
535 
536             executeShellCmd("cmd deviceidle tempwhitelist -r " + SIMPLE_PACKAGE_NAME);
537 
538             // Going off the temp whitelist causes a spurious proc state report...  that's
539             // not ideal, but okay.
540             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
541 
542             // We don't want to wait for the uid to actually go idle, we can force it now.
543             cmd = "am make-uid-idle " + SIMPLE_PACKAGE_NAME;
544             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
545 
546             uidWatcher.expect(WatchUidRunner.CMD_IDLE, null);
547             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
548 
549             // Now that we should be off the temp whitelist, make sure we again can't start.
550             failed = false;
551             try {
552                 mContext.startService(serviceIntent);
553             } catch (IllegalStateException e) {
554                 failed = true;
555             }
556             if (!failed) {
557                 fail("Service was allowed to start while in the background");
558             }
559 
560             // Now put app on whitelist, should allow service to run.
561             cmd = "cmd deviceidle whitelist +" + SIMPLE_PACKAGE_NAME;
562             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
563 
564             // Try starting the service now that the app is whitelisted...  should work!
565             mContext.startService(serviceIntent);
566             conn.waitForConnect();
567 
568             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
569             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
570 
571             // Okay, bring down the service.
572             mContext.stopService(serviceIntent);
573             conn.waitForDisconnect();
574 
575             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
576             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
577 
578         } finally {
579             mContext.stopService(serviceIntent);
580             conn.stopMonitoring();
581 
582             uidWatcher.finish();
583 
584             cmd = "appops set " + SIMPLE_PACKAGE_NAME + " RUN_IN_BACKGROUND allow";
585             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
586             cmd = "cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME;
587             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
588 
589             uidGoneListener.unregister();
590             uidForegroundListener.unregister();
591 
592             data.recycle();
593         }
594     }
595 
596     /**
597      * Test that background check behaves correctly after a process is no longer foreground:
598      * first allowing a service to be started, then stopped by the system when idle.
599      */
testBackgroundCheckStopsService()600     public void testBackgroundCheckStopsService() throws Exception {
601         final Parcel data = Parcel.obtain();
602         ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext, mServiceIntent,
603                 WAIT_TIME);
604         ServiceConnectionHandler conn2 = new ServiceConnectionHandler(mContext, mService2Intent,
605                 WAIT_TIME);
606 
607         ActivityManager am = mContext.getSystemService(ActivityManager.class);
608 
609         InstrumentationRegistry.getInstrumentation().getUiAutomation().grantRuntimePermission(
610                 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS);
611         /*
612         Log.d("XXXX", "Invoke: " + cmd);
613         Log.d("XXXX", "Result: " + result);
614         Log.d("XXXX", SystemUtil.runShellCommand(getInstrumentation(), "dumpsys package "
615                 + STUB_PACKAGE_NAME));
616         */
617 
618         ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo(
619                 SIMPLE_PACKAGE_NAME, 0);
620 
621         UidImportanceListener uidServiceListener = new UidImportanceListener(mContext,
622                 appInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE, WAIT_TIME);
623         uidServiceListener.register();
624         UidImportanceListener uidGoneListener = new UidImportanceListener(mContext,
625                 appInfo.uid, IMPORTANCE_CACHED, WAIT_TIME);
626         uidGoneListener.register();
627 
628         WatchUidRunner uidWatcher = new WatchUidRunner(getInstrumentation(), appInfo.uid,
629                 WAIT_TIME);
630 
631         // First kill the process to start out in a stable state.
632         mContext.stopService(mServiceIntent);
633         mContext.stopService(mService2Intent);
634         conn.bind();
635         conn2.bind();
636         IBinder service = conn.getServiceIBinder();
637         IBinder service2 = conn2.getServiceIBinder();
638         conn.unbind();
639         conn2.unbind();
640         try {
641             service.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0);
642         } catch (RemoteException e) {
643         }
644         try {
645             service2.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0);
646         } catch (RemoteException e) {
647         }
648         service = service2 = null;
649 
650         // Wait for uid's process to go away.
651         uidGoneListener.waitForValue(IMPORTANCE_GONE,
652                 IMPORTANCE_GONE);
653         assertEquals(IMPORTANCE_GONE,
654                 am.getPackageImportance(SIMPLE_PACKAGE_NAME));
655 
656         // And wait for the uid report to be gone.
657         uidWatcher.waitFor(WatchUidRunner.CMD_GONE, null, WAIT_TIME);
658 
659         String cmd = "appops set " + SIMPLE_PACKAGE_NAME + " RUN_IN_BACKGROUND deny";
660         String result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
661 
662         // This is a side-effect of the app op command.
663         uidWatcher.expect(WatchUidRunner.CMD_IDLE, null);
664         uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_NONEXISTENT);
665 
666         // We don't want to wait for the uid to actually go idle, we can force it now.
667         cmd = "am make-uid-idle " + SIMPLE_PACKAGE_NAME;
668         result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
669 
670         // Make sure app is not yet on whitelist
671         cmd = "cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME;
672         result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
673 
674         // We will use this to monitor when the service is running.
675         conn.startMonitoring();
676 
677         try {
678             // Try starting the service.  Should fail!
679             boolean failed = false;
680             try {
681                 mContext.startService(mServiceIntent);
682             } catch (IllegalStateException e) {
683                 failed = true;
684             }
685             if (!failed) {
686                 fail("Service was allowed to start while in the background");
687             }
688 
689             // First poke the process into the foreground, so we can avoid background check.
690             conn2.bind();
691             conn2.waitForConnect();
692 
693             // Wait for process state to reflect running service.
694             uidServiceListener.waitForValue(
695                     IMPORTANCE_FOREGROUND_SERVICE,
696                     ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE);
697             assertEquals(IMPORTANCE_FOREGROUND_SERVICE,
698                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
699 
700             // Also make sure the uid state reports are as expected.
701             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
702             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
703             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
704 
705             conn2.unbind();
706 
707             // Wait for process to recover back down to being cached.
708             uidServiceListener.waitForValue(IMPORTANCE_CACHED,
709                     IMPORTANCE_GONE);
710             assertEquals(IMPORTANCE_CACHED,
711                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
712 
713             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null);
714             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
715 
716             // Try starting the service now that the app is waiting to idle...  should work!
717             mContext.startService(mServiceIntent);
718             conn.waitForConnect();
719 
720             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
721             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
722 
723             // And also start the second service.
724             conn2.startMonitoring();
725             mContext.startService(mService2Intent);
726             conn2.waitForConnect();
727 
728             // Force app to go idle now
729             cmd = "am make-uid-idle " + SIMPLE_PACKAGE_NAME;
730             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
731 
732             // Wait for services to be stopped by system.
733             uidServiceListener.waitForValue(IMPORTANCE_CACHED,
734                     IMPORTANCE_GONE);
735             assertEquals(IMPORTANCE_CACHED,
736                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
737 
738             // And service should be stopped by system, so just make sure it is disconnected.
739             conn.waitForDisconnect();
740             conn2.waitForDisconnect();
741 
742             uidWatcher.expect(WatchUidRunner.CMD_IDLE, null);
743             // There may be a transient 'SVC' proc state here.
744             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null);
745             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
746 
747         } finally {
748             mContext.stopService(mServiceIntent);
749             mContext.stopService(mService2Intent);
750             conn.cleanup();
751             conn2.cleanup();
752 
753             uidWatcher.finish();
754 
755             cmd = "appops set " + SIMPLE_PACKAGE_NAME + " RUN_IN_BACKGROUND allow";
756             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
757             cmd = "cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME;
758             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
759 
760             uidGoneListener.unregister();
761             uidServiceListener.unregister();
762 
763             data.recycle();
764         }
765     }
766 
767     /**
768      * Test the background check doesn't allow services to be started from broadcasts except
769      * when in the correct states.
770      */
testBackgroundCheckBroadcastService()771     public void testBackgroundCheckBroadcastService() throws Exception {
772         final Intent broadcastIntent = new Intent();
773         broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
774         broadcastIntent.setClassName(SIMPLE_PACKAGE_NAME,
775                 SIMPLE_PACKAGE_NAME + SIMPLE_RECEIVER_START_SERVICE);
776 
777         final ServiceProcessController controller = new ServiceProcessController(mContext,
778                 getInstrumentation(), STUB_PACKAGE_NAME, mAllProcesses, WAIT_TIME);
779         final ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext,
780                 mServiceIntent, WAIT_TIME);
781         final WatchUidRunner uidWatcher = controller.getUidWatcher();
782 
783         try {
784             // First kill the process to start out in a stable state.
785             controller.ensureProcessGone();
786 
787             // Do initial setup.
788             controller.denyBackgroundOp();
789             controller.makeUidIdle();
790             controller.removeFromWhitelist();
791 
792             // We will use this to monitor when the service is running.
793             conn.startMonitoring();
794 
795             // Try sending broadcast to start the service.  Should fail!
796             SyncOrderedBroadcast br = new SyncOrderedBroadcast();
797             broadcastIntent.putExtra("service", mServiceIntent);
798             br.sendAndWait(mContext, broadcastIntent, Activity.RESULT_OK, null, null, WAIT_TIME);
799             int brCode = br.getReceivedCode();
800             if (brCode != Activity.RESULT_CANCELED) {
801                 fail("Didn't fail starting service, result=" + brCode);
802             }
803 
804             // Track the uid proc state changes from the broadcast (but not service execution)
805             uidWatcher.waitFor(WatchUidRunner.CMD_IDLE, null, WAIT_TIME);
806             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
807             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_RECEIVER, WAIT_TIME);
808             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null, WAIT_TIME);
809             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY, WAIT_TIME);
810 
811             // Put app on temporary whitelist to see if this allows the service start.
812             controller.tempWhitelist(TEMP_WHITELIST_DURATION_MS);
813 
814             // Being on the whitelist means the uid is now active.
815             uidWatcher.expect(WatchUidRunner.CMD_ACTIVE, null, WAIT_TIME);
816             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY, WAIT_TIME);
817 
818             // Try starting the service now that the app is whitelisted...  should work!
819             br.sendAndWait(mContext, broadcastIntent, Activity.RESULT_OK, null, null, WAIT_TIME);
820             brCode = br.getReceivedCode();
821             if (brCode != Activity.RESULT_FIRST_USER) {
822                 fail("Failed starting service, result=" + brCode);
823             }
824             conn.waitForConnect();
825 
826             // Also make sure the uid state reports are as expected.
827             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
828             // We are going to wait until 'SVC', because we may see an intermediate 'RCVR'
829             // proc state depending on timing.
830             uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
831 
832             // Good, now stop the service and give enough time to get off the temp whitelist.
833             mContext.stopService(mServiceIntent);
834             conn.waitForDisconnect();
835 
836             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
837             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
838 
839             controller.removeFromTempWhitelist();
840 
841             // Going off the temp whitelist causes a spurious proc state report...  that's
842             // not ideal, but okay.
843             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
844 
845             // We don't want to wait for the uid to actually go idle, we can force it now.
846             controller.makeUidIdle();
847 
848             uidWatcher.expect(WatchUidRunner.CMD_IDLE, null);
849 
850             // Make sure the process is gone so we start over fresh.
851             controller.ensureProcessGone();
852 
853             // Now that we should be off the temp whitelist, make sure we again can't start.
854             br.sendAndWait(mContext, broadcastIntent, Activity.RESULT_OK, null, null, WAIT_TIME);
855             brCode = br.getReceivedCode();
856             if (brCode != Activity.RESULT_CANCELED) {
857                 fail("Didn't fail starting service, result=" + brCode);
858             }
859 
860             // Track the uid proc state changes from the broadcast (but not service execution)
861             uidWatcher.waitFor(WatchUidRunner.CMD_IDLE, null);
862             // There could be a transient 'cached' state here before 'uncached' if uid state
863             // changes are dispatched before receiver is started.
864             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
865             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_RECEIVER);
866             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
867             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
868 
869             // Now put app on whitelist, should allow service to run.
870             controller.addToWhitelist();
871 
872             // Try starting the service now that the app is whitelisted...  should work!
873             br.sendAndWait(mContext, broadcastIntent, Activity.RESULT_OK, null, null, WAIT_TIME);
874             brCode = br.getReceivedCode();
875             if (brCode != Activity.RESULT_FIRST_USER) {
876                 fail("Failed starting service, result=" + brCode);
877             }
878             conn.waitForConnect();
879 
880             // Also make sure the uid state reports are as expected.
881             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
882             uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
883 
884             // Okay, bring down the service.
885             mContext.stopService(mServiceIntent);
886             conn.waitForDisconnect();
887 
888             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
889             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
890 
891         } finally {
892             mContext.stopService(mServiceIntent);
893             conn.stopMonitoringIfNeeded();
894             controller.cleanup();
895         }
896     }
897 
898     /**
899      * Test that background check does allow services to be started from activities.
900      */
testBackgroundCheckActivityService()901     public void testBackgroundCheckActivityService() throws Exception {
902         final Intent activityIntent = new Intent();
903         activityIntent.setClassName(SIMPLE_PACKAGE_NAME,
904                 SIMPLE_PACKAGE_NAME + SIMPLE_ACTIVITY_START_SERVICE);
905         activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
906 
907         final ServiceProcessController controller = new ServiceProcessController(mContext,
908                 getInstrumentation(), STUB_PACKAGE_NAME, mAllProcesses, WAIT_TIME);
909         final ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext,
910                 mServiceIntent, WAIT_TIME);
911         final WatchUidRunner uidWatcher = controller.getUidWatcher();
912 
913         try {
914             // First kill the process to start out in a stable state.
915             controller.ensureProcessGone();
916 
917             // Do initial setup.
918             controller.denyBackgroundOp();
919             controller.makeUidIdle();
920             controller.removeFromWhitelist();
921 
922             // We will use this to monitor when the service is running.
923             conn.startMonitoring();
924 
925             // Try starting activity that will start the service.  This should be okay.
926             WaitForBroadcast waiter = new WaitForBroadcast(mInstrumentation.getTargetContext());
927             waiter.prepare(ACTION_SIMPLE_ACTIVITY_START_SERVICE_RESULT);
928             activityIntent.putExtra("service", mServiceIntent);
929             mContext.startActivity(activityIntent);
930             Intent resultIntent = waiter.doWait(WAIT_TIME);
931             int brCode = resultIntent.getIntExtra("result", Activity.RESULT_CANCELED);
932             if (brCode != Activity.RESULT_FIRST_USER) {
933                 fail("Failed starting service, result=" + brCode);
934             }
935             conn.waitForConnect();
936 
937             final String expectedActivityState = (isScreenInteractive() && !isKeyguardLocked())
938                     ? WatchUidRunner.STATE_TOP : WatchUidRunner.STATE_TOP_SLEEPING;
939             // Also make sure the uid state reports are as expected.
940             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
941             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
942             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, expectedActivityState);
943             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
944 
945             // Okay, bring down the service.
946             mContext.stopService(mServiceIntent);
947             conn.waitForDisconnect();
948 
949             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
950             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
951 
952             // App isn't yet idle, so we should be able to start the service again.
953             mContext.startService(mServiceIntent);
954             conn.waitForConnect();
955             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
956             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
957 
958             // And now fast-forward to the app going idle, service should be stopped.
959             controller.makeUidIdle();
960             uidWatcher.waitFor(WatchUidRunner.CMD_IDLE, null);
961 
962             conn.waitForDisconnect();
963             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null);
964             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
965 
966             // No longer should be able to start service.
967             boolean failed = false;
968             try {
969                 mContext.startService(mServiceIntent);
970             } catch (IllegalStateException e) {
971                 failed = true;
972             }
973             if (!failed) {
974                 fail("Service was allowed to start while in the background");
975             }
976 
977         } finally {
978             mContext.stopService(mServiceIntent);
979             conn.stopMonitoringIfNeeded();
980             controller.cleanup();
981         }
982     }
983 
984     /**
985      * Test that the foreground service app op does prevent the foreground state.
986      */
testForegroundServiceAppOp()987     public void testForegroundServiceAppOp() throws Exception {
988         // Use default timeout value 5000
989         final ServiceProcessController controller = new ServiceProcessController(mContext,
990                 getInstrumentation(), STUB_PACKAGE_NAME, mAllProcesses);
991         // Use default timeout value 5000
992         final ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext,
993                 mServiceIntent);
994         final WatchUidRunner uidWatcher = controller.getUidWatcher();
995 
996         try {
997             // First kill the process to start out in a stable state.
998             controller.ensureProcessGone();
999 
1000             // Do initial setup.
1001             controller.makeUidIdle();
1002             controller.removeFromWhitelist();
1003             controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "allow");
1004 
1005             // Put app on whitelist, to allow service to run.
1006             controller.addToWhitelist();
1007 
1008             // We will use this to monitor when the service is running.
1009             conn.startMonitoring();
1010 
1011             // -------- START SERVICE AND THEN SUCCESSFULLY GO TO FOREGROUND
1012 
1013             // Now start the service and wait for it to come up.
1014             mContext.startService(mServiceStartForegroundIntent);
1015             conn.waitForConnect();
1016 
1017             // Also make sure the uid state reports are as expected.
1018             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1019             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
1020             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
1021             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1022 
1023             // Now take it out of foreground and confirm.
1024             mContext.startService(mServiceStopForegroundIntent);
1025             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
1026 
1027             // Good, now stop the service and wait for it to go away.
1028             mContext.stopService(mServiceStartForegroundIntent);
1029             conn.waitForDisconnect();
1030 
1031             // There may be a transient STATE_SERVICE we don't care about, so waitFor.
1032             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null);
1033             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1034 
1035             // We don't want to wait for the uid to actually go idle, we can force it now.
1036             controller.makeUidIdle();
1037             uidWatcher.expect(WatchUidRunner.CMD_IDLE, null);
1038 
1039             // Make sure the process is gone so we start over fresh.
1040             controller.ensureProcessGone();
1041 
1042             // -------- START SERVICE AND BLOCK GOING TO FOREGROUND
1043 
1044             // Now we will deny the app op and ensure the service can't become foreground.
1045             controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "ignore");
1046 
1047             // Now start the service and wait for it to come up.
1048             mContext.startService(mServiceStartForegroundIntent);
1049             conn.waitForConnect();
1050 
1051             // Also make sure the uid state reports are as expected.
1052             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1053             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
1054 
1055             // Good, now stop the service and wait for it to go away.
1056             mContext.stopService(mServiceStartForegroundIntent);
1057             conn.waitForDisconnect();
1058 
1059             // THIS MUST BE AN EXPECT: we want to make sure we don't get in to STATE_FG_SERVICE.
1060             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
1061             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1062 
1063             // Make sure the uid is idle (it should be anyway, it never went active here).
1064             controller.makeUidIdle();
1065 
1066             // Make sure the process is gone so we start over fresh.
1067             controller.ensureProcessGone();
1068 
1069             // -------- DIRECT START FOREGROUND SERVICE SUCCESSFULLY
1070 
1071             controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "allow");
1072 
1073             // Now start the service and wait for it to come up.
1074             mContext.startForegroundService(mServiceStartForegroundIntent);
1075             conn.waitForConnect();
1076 
1077             // Make sure it becomes a foreground service.  The process state changes here
1078             // are weird looking because we first need to force the app out of idle to allow
1079             // it to start the service.
1080             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
1081             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1082             uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1083             // Remove tempwhitelist avoid temp white list block idle command and app crash occur.
1084             executeShellCmd("cmd deviceidle tempwhitelist -r " + SIMPLE_PACKAGE_NAME);
1085             // Good, now stop the service and wait for it to go away.
1086             mContext.stopService(mServiceStartForegroundIntent);
1087             conn.waitForDisconnect();
1088 
1089             // There may be a transient STATE_SERVICE we don't care about, so waitFor.
1090             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null);
1091             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1092 
1093             // We don't want to wait for the uid to actually go idle, we can force it now.
1094             controller.makeUidIdle();
1095 
1096             // Make sure the process is gone so we start over fresh.
1097             controller.ensureProcessGone();
1098 
1099             // -------- DIRECT START FOREGROUND SERVICE BLOCKED
1100 
1101             // Now we will deny the app op and ensure the service can't become foreground.
1102             controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "ignore");
1103 
1104             // But we will put it on the whitelist so the service is still allowed to start.
1105             controller.addToWhitelist();
1106 
1107             // Now start the service and wait for it to come up.
1108             mContext.startForegroundService(mServiceStartForegroundIntent);
1109             conn.waitForConnect();
1110 
1111             // In this case we only get to run it as a regular service.
1112             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1113             uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
1114 
1115             // Good, now stop the service and wait for it to go away.
1116             mContext.stopService(mServiceStartForegroundIntent);
1117             conn.waitForDisconnect();
1118 
1119             // THIS MUST BE AN EXPECT: we want to make sure we don't get in to STATE_FG_SERVICE.
1120             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
1121             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1122 
1123             // Make sure the uid is idle (it should be anyway, it never went active here).
1124             controller.makeUidIdle();
1125 
1126             // Make sure the process is gone so we start over fresh.
1127             controller.ensureProcessGone();
1128 
1129             // -------- XXX NEED TO TEST NON-WHITELIST CASE WHERE NOTHING HAPPENS
1130 
1131         } finally {
1132             mContext.stopService(mServiceStartForegroundIntent);
1133             conn.stopMonitoringIfNeeded();
1134             controller.cleanup();
1135             controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "allow");
1136             controller.removeFromWhitelist();
1137         }
1138     }
1139 
1140     /**
1141      * Verify that an app under background restrictions has its foreground services
1142      * demoted to ordinary service state when it is no longer the top app.
1143      */
testBgRestrictedForegroundService()1144     public void testBgRestrictedForegroundService() throws Exception {
1145         final Intent activityIntent = new Intent()
1146                 .setClassName(SIMPLE_PACKAGE_NAME,
1147                         SIMPLE_PACKAGE_NAME + SIMPLE_ACTIVITY_START_FG_SERVICE)
1148                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1149 
1150         final ServiceProcessController controller = new ServiceProcessController(mContext,
1151                 getInstrumentation(), STUB_PACKAGE_NAME, mAllProcesses, WAIT_TIME);
1152         final WatchUidRunner uidWatcher = controller.getUidWatcher();
1153 
1154         final Intent homeIntent = new Intent()
1155                 .setAction(Intent.ACTION_MAIN)
1156                 .addCategory(Intent.CATEGORY_HOME)
1157                 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
1158                         | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
1159 
1160         final Intent serviceStartIntent = new Intent(mService3Intent)
1161                 .setAction(ACTION_START_THEN_FG);
1162         activityIntent.putExtra("service", serviceStartIntent);
1163         boolean activityStarted = false;
1164 
1165         try {
1166             // First kill the process to start out in a stable state.
1167             controller.ensureProcessGone();
1168 
1169             // Do initial setup.
1170             controller.denyAnyInBackgroundOp();
1171             controller.makeUidIdle();
1172             controller.removeFromWhitelist();
1173             controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "allow");
1174 
1175             // Start the activity, which will start the fg service as well, and wait
1176             // for the report that it's all up and running.
1177             WaitForBroadcast waiter = new WaitForBroadcast(mInstrumentation.getTargetContext());
1178             waiter.prepare(ACTION_SIMPLE_ACTIVITY_START_FG_SERVICE_RESULT);
1179 
1180             activityIntent.setAction(ACTION_SIMPLE_ACTIVITY_START_FG);
1181             mContext.startActivity(activityIntent);
1182             activityStarted = true;
1183 
1184             Intent resultIntent = waiter.doWait(WAIT_TIME);
1185             int brCode = resultIntent.getIntExtra("result", Activity.RESULT_CANCELED);
1186             if (brCode != Activity.RESULT_FIRST_USER) {
1187                 fail("Failed starting service, result=" + brCode);
1188             }
1189 
1190             // activity is in front, fg service is running.  make sure that we see
1191             // the expected state at this point.
1192             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
1193             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1194             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP);
1195 
1196             // Switch to the home app; make sure the test app drops all the way
1197             // down to SERVICE, not FG_SERVICE
1198             mContext.startActivity(homeIntent);
1199             uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE);
1200         } finally {
1201             // tear down everything and we're done
1202             if (activityStarted) {
1203                 activityIntent.setAction(ACTION_FINISH_EVERYTHING);
1204                 mContext.startActivity(activityIntent);
1205             }
1206 
1207             controller.cleanup();
1208         }
1209 
1210     }
1211 
supportsCantSaveState()1212     private boolean supportsCantSaveState() {
1213         if (mContext.getPackageManager().hasSystemFeature(
1214                 PackageManager.FEATURE_CANT_SAVE_STATE)) {
1215             return true;
1216         }
1217 
1218         // Most types of devices need to support this.
1219         int mode = mContext.getResources().getConfiguration().uiMode
1220                 & Configuration.UI_MODE_TYPE_MASK;
1221         if (mode != Configuration.UI_MODE_TYPE_WATCH
1222                 && mode != Configuration.UI_MODE_TYPE_APPLIANCE) {
1223             // Most devices must support the can't save state feature.
1224             throw new IllegalStateException("Devices that are not watches or appliances must "
1225                     + "support FEATURE_CANT_SAVE_STATE");
1226         }
1227         return false;
1228     }
1229 
1230     /**
1231      * Test that a single "can't save state" app has the proper process management
1232      * semantics.
1233      */
testCantSaveStateLaunchAndBackground()1234     public void testCantSaveStateLaunchAndBackground() throws Exception {
1235         if (!supportsCantSaveState()) {
1236             return;
1237         }
1238 
1239         final Intent activityIntent = new Intent();
1240         activityIntent.setPackage(CANT_SAVE_STATE_1_PACKAGE_NAME);
1241         activityIntent.setAction(Intent.ACTION_MAIN);
1242         activityIntent.addCategory(Intent.CATEGORY_LAUNCHER);
1243         activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1244 
1245         final Intent homeIntent = new Intent();
1246         homeIntent.setAction(Intent.ACTION_MAIN);
1247         homeIntent.addCategory(Intent.CATEGORY_HOME);
1248         homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1249 
1250         ActivityManager am = mContext.getSystemService(ActivityManager.class);
1251 
1252         InstrumentationRegistry.getInstrumentation().getUiAutomation().grantRuntimePermission(
1253                 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS);
1254 
1255         // We don't want to wait for the uid to actually go idle, we can force it now.
1256         String cmd = "am make-uid-idle " + CANT_SAVE_STATE_1_PACKAGE_NAME;
1257         String result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
1258 
1259         ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo(
1260                 CANT_SAVE_STATE_1_PACKAGE_NAME, 0);
1261 
1262         // This test is also using UidImportanceListener to make sure the correct
1263         // heavy-weight state is reported there.
1264         UidImportanceListener uidForegroundListener = new UidImportanceListener(mContext,
1265                 appInfo.uid, IMPORTANCE_FOREGROUND,
1266                 WAIT_TIME);
1267         uidForegroundListener.register();
1268         UidImportanceListener uidBackgroundListener = new UidImportanceListener(mContext,
1269                 appInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE-1,
1270                 WAIT_TIME);
1271         uidBackgroundListener.register();
1272 
1273         WatchUidRunner uidWatcher = new WatchUidRunner(getInstrumentation(), appInfo.uid,
1274                 WAIT_TIME);
1275 
1276         UiDevice device = UiDevice.getInstance(getInstrumentation());
1277 
1278         try {
1279             // Start the heavy-weight app, should launch like a normal app.
1280             mContext.startActivity(activityIntent);
1281             waitForAppFocus(CANT_SAVE_STATE_1_PACKAGE_NAME, WAIT_TIME);
1282             device.waitForIdle();
1283 
1284             // Wait for process state to reflect running activity.
1285             uidForegroundListener.waitForValue(
1286                     IMPORTANCE_FOREGROUND,
1287                     IMPORTANCE_FOREGROUND);
1288             assertEquals(IMPORTANCE_FOREGROUND,
1289                     am.getPackageImportance(CANT_SAVE_STATE_1_PACKAGE_NAME));
1290 
1291             // Also make sure the uid state reports are as expected.
1292             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
1293             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1294             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP);
1295 
1296             // Now go to home, leaving the app.  It should be put in the heavy weight state.
1297             mContext.startActivity(homeIntent);
1298 
1299             final int expectedImportance =
1300                     (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O)
1301                             ? ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE
1302                             : ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE_PRE_26;
1303             // Wait for process to go down to background heavy-weight.
1304             uidBackgroundListener.waitForValue(expectedImportance, expectedImportance);
1305             assertEquals(expectedImportance,
1306                     am.getPackageImportance(CANT_SAVE_STATE_1_PACKAGE_NAME));
1307 
1308             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
1309             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_HEAVY_WEIGHT);
1310 
1311             // While in background, should go in to normal idle state.
1312             // Force app to go idle now
1313             cmd = "am make-uid-idle " + CANT_SAVE_STATE_1_PACKAGE_NAME;
1314             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
1315             uidWatcher.expect(WatchUidRunner.CMD_IDLE, null);
1316 
1317             // Switch back to heavy-weight app to see if it correctly returns to foreground.
1318             mContext.startActivity(activityIntent);
1319 
1320             // Wait for process state to reflect running activity.
1321             uidForegroundListener.waitForValue(
1322                     IMPORTANCE_FOREGROUND,
1323                     IMPORTANCE_FOREGROUND);
1324             assertEquals(IMPORTANCE_FOREGROUND,
1325                     am.getPackageImportance(CANT_SAVE_STATE_1_PACKAGE_NAME));
1326 
1327             // Also make sure the uid state reports are as expected.
1328             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
1329             uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1330             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP);
1331 
1332             waitForAppFocus(CANT_SAVE_STATE_1_PACKAGE_NAME, WAIT_TIME);
1333             device.waitForIdle();
1334 
1335             // Exit activity, check to see if we are now cached.
1336             getInstrumentation().getUiAutomation().performGlobalAction(
1337                     AccessibilityService.GLOBAL_ACTION_BACK);
1338 
1339             // Wait for process to become cached
1340             uidBackgroundListener.waitForValue(
1341                     IMPORTANCE_CACHED,
1342                     IMPORTANCE_CACHED);
1343             assertEquals(IMPORTANCE_CACHED,
1344                     am.getPackageImportance(CANT_SAVE_STATE_1_PACKAGE_NAME));
1345 
1346             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null);
1347             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_RECENT);
1348 
1349             // While in background, should go in to normal idle state.
1350             // Force app to go idle now
1351             cmd = "am make-uid-idle " + CANT_SAVE_STATE_1_PACKAGE_NAME;
1352             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
1353             uidWatcher.expect(WatchUidRunner.CMD_IDLE, null);
1354 
1355         } finally {
1356             uidWatcher.finish();
1357             uidForegroundListener.unregister();
1358             uidBackgroundListener.unregister();
1359         }
1360     }
1361 
1362     /**
1363      * Test that switching between two "can't save state" apps is handled properly.
1364      */
testCantSaveStateLaunchAndSwitch()1365     public void testCantSaveStateLaunchAndSwitch() throws Exception {
1366         if (!supportsCantSaveState()) {
1367             return;
1368         }
1369 
1370         final Intent activity1Intent = new Intent();
1371         activity1Intent.setPackage(CANT_SAVE_STATE_1_PACKAGE_NAME);
1372         activity1Intent.setAction(Intent.ACTION_MAIN);
1373         activity1Intent.addCategory(Intent.CATEGORY_LAUNCHER);
1374         activity1Intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1375 
1376         final Intent activity2Intent = new Intent();
1377         activity2Intent.setPackage(CANT_SAVE_STATE_2_PACKAGE_NAME);
1378         activity2Intent.setAction(Intent.ACTION_MAIN);
1379         activity2Intent.addCategory(Intent.CATEGORY_LAUNCHER);
1380         activity2Intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1381 
1382         final Intent homeIntent = new Intent();
1383         homeIntent.setAction(Intent.ACTION_MAIN);
1384         homeIntent.addCategory(Intent.CATEGORY_HOME);
1385         homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1386 
1387         ActivityManager am = mContext.getSystemService(ActivityManager.class);
1388         UiDevice device = UiDevice.getInstance(getInstrumentation());
1389 
1390         InstrumentationRegistry.getInstrumentation().getUiAutomation().grantRuntimePermission(
1391                 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS);
1392 
1393         // We don't want to wait for the uid to actually go idle, we can force it now.
1394         String cmd = "am make-uid-idle " + CANT_SAVE_STATE_1_PACKAGE_NAME;
1395         String result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
1396         cmd = "am make-uid-idle " + CANT_SAVE_STATE_2_PACKAGE_NAME;
1397         result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
1398 
1399         ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo(
1400                 CANT_SAVE_STATE_1_PACKAGE_NAME, 0);
1401         WatchUidRunner uid1Watcher = new WatchUidRunner(getInstrumentation(), app1Info.uid,
1402                 WAIT_TIME);
1403 
1404         ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo(
1405                 CANT_SAVE_STATE_2_PACKAGE_NAME, 0);
1406         WatchUidRunner uid2Watcher = new WatchUidRunner(getInstrumentation(), app2Info.uid,
1407                 WAIT_TIME);
1408 
1409         try {
1410             // Start the first heavy-weight app, should launch like a normal app.
1411             mContext.startActivity(activity1Intent);
1412             waitForAppFocus(CANT_SAVE_STATE_1_PACKAGE_NAME, WAIT_TIME);
1413             device.waitForIdle();
1414 
1415             // Make sure the uid state reports are as expected.
1416             uid1Watcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
1417             uid1Watcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1418             uid1Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP);
1419 
1420             // Now go to home, leaving the app.  It should be put in the heavy weight state.
1421             mContext.startActivity(homeIntent);
1422 
1423             // Wait for process to go down to background heavy-weight.
1424             uid1Watcher.expect(WatchUidRunner.CMD_CACHED, null);
1425             uid1Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_HEAVY_WEIGHT);
1426 
1427             // Start the second heavy-weight app, should ask us what to do with the two apps
1428             startActivityAndWaitForShow(activity2Intent);
1429 
1430             // First, let's try returning to the original app.
1431             maybeClick(device, new UiSelector().resourceId("android:id/switch_old"));
1432             waitForAppFocus(CANT_SAVE_STATE_1_PACKAGE_NAME, WAIT_TIME);
1433             device.waitForIdle();
1434 
1435             // App should now be back in foreground.
1436             uid1Watcher.expect(WatchUidRunner.CMD_UNCACHED, null);
1437             uid1Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP);
1438 
1439             // Return to home.
1440             mContext.startActivity(homeIntent);
1441             uid1Watcher.expect(WatchUidRunner.CMD_CACHED, null);
1442             uid1Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_HEAVY_WEIGHT);
1443 
1444             // Again try starting second heavy-weight app to get prompt.
1445             startActivityAndWaitForShow(activity2Intent);
1446 
1447             // Now we'll switch to the new app.
1448             maybeClick(device, new UiSelector().resourceId("android:id/switch_new"));
1449             waitForAppFocus(CANT_SAVE_STATE_2_PACKAGE_NAME, WAIT_TIME);
1450             device.waitForIdle();
1451 
1452             // The original app should now become cached.
1453             uid1Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_RECENT);
1454 
1455             // And the new app should start.
1456             uid2Watcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
1457             uid2Watcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1458             uid2Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP);
1459 
1460             // Make sure the original app is idle for cleanliness
1461             cmd = "am make-uid-idle " + CANT_SAVE_STATE_1_PACKAGE_NAME;
1462             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
1463             uid1Watcher.expect(WatchUidRunner.CMD_IDLE, null);
1464 
1465             // Return to home.
1466             mContext.startActivity(homeIntent);
1467             uid2Watcher.waitFor(WatchUidRunner.CMD_CACHED, null);
1468             uid2Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_HEAVY_WEIGHT);
1469 
1470             // Try starting the first heavy weight app, but return to the existing second.
1471             startActivityAndWaitForShow(activity1Intent);
1472             maybeClick(device, new UiSelector().resourceId("android:id/switch_old"));
1473             waitForAppFocus(CANT_SAVE_STATE_2_PACKAGE_NAME, WAIT_TIME);
1474             device.waitForIdle();
1475             uid2Watcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1476             uid2Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP);
1477 
1478             // Return to home.
1479             mContext.startActivity(homeIntent);
1480             uid2Watcher.waitFor(WatchUidRunner.CMD_CACHED, null);
1481             uid2Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_HEAVY_WEIGHT);
1482 
1483             // Again start the first heavy weight app, this time actually switching to it
1484             startActivityAndWaitForShow(activity1Intent);
1485             maybeClick(device, new UiSelector().resourceId("android:id/switch_new"));
1486             waitForAppFocus(CANT_SAVE_STATE_1_PACKAGE_NAME, WAIT_TIME);
1487             device.waitForIdle();
1488 
1489             // The second app should now become cached.
1490             uid2Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_RECENT);
1491 
1492             // And the first app should start.
1493             uid1Watcher.waitFor(WatchUidRunner.CMD_ACTIVE, null);
1494             uid1Watcher.waitFor(WatchUidRunner.CMD_UNCACHED, null);
1495             uid1Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP);
1496 
1497             // Exit activity, check to see if we are now cached.
1498             waitForAppFocus(CANT_SAVE_STATE_1_PACKAGE_NAME, WAIT_TIME);
1499             device.waitForIdle();
1500             getInstrumentation().getUiAutomation().performGlobalAction(
1501                     AccessibilityService.GLOBAL_ACTION_BACK);
1502             uid1Watcher.expect(WatchUidRunner.CMD_CACHED, null);
1503             uid1Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_RECENT);
1504 
1505             // Make both apps idle for cleanliness.
1506             cmd = "am make-uid-idle " + CANT_SAVE_STATE_1_PACKAGE_NAME;
1507             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
1508             cmd = "am make-uid-idle " + CANT_SAVE_STATE_2_PACKAGE_NAME;
1509             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
1510 
1511         } finally {
1512             uid2Watcher.finish();
1513             uid1Watcher.finish();
1514         }
1515     }
1516 
1517     /**
1518      * Test a service binding cycle between two apps, with one of them also running a
1519      * foreground service. The other app should also get an FGS proc state. On stopping the
1520      * foreground service, app should go back to cached state.
1521      * @throws Exception
1522      */
testCycleFgs()1523     public void testCycleFgs() throws Exception {
1524         ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo(
1525                 PACKAGE_NAME_APP1, 0);
1526         ApplicationInfo app3Info = mContext.getPackageManager().getApplicationInfo(
1527                 PACKAGE_NAME_APP3, 0);
1528         WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid,
1529                 WAITFOR_MSEC);
1530         WatchUidRunner uid3Watcher = new WatchUidRunner(mInstrumentation, app3Info.uid,
1531                 WAITFOR_MSEC);
1532 
1533         try {
1534             CommandReceiver.sendCommand(mContext,
1535                     CommandReceiver.COMMAND_START_FOREGROUND_SERVICE,
1536                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
1537             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1538 
1539             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1540                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP3, 0, null);
1541 
1542             uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1543 
1544             // Create a cycle
1545             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1546                     PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null);
1547 
1548             try {
1549                 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
1550                         WatchUidRunner.STATE_CACHED_EMPTY);
1551                 fail("App3 should not be demoted to cached");
1552             } catch (IllegalStateException ise) {
1553                 // Didn't go to cached in spite of cycle. Good!
1554             }
1555 
1556             // Stop the foreground service
1557             CommandReceiver.sendCommand(mContext, CommandReceiver
1558                             .COMMAND_STOP_FOREGROUND_SERVICE,
1559                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
1560 
1561             // Check that the app's proc state has fallen
1562             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1563             uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1564 
1565             // Clean up: unbind services to avoid from interferences with other tests
1566             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1567                 PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null);
1568             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1569                 PACKAGE_NAME_APP1, PACKAGE_NAME_APP3, 0, null);
1570         } finally {
1571             uid1Watcher.finish();
1572             uid3Watcher.finish();
1573         }
1574     }
1575 
1576     /**
1577      * Test a service binding cycle between three apps, with one of them also running a
1578      * foreground service. The other apps should also get an FGS proc state. On stopping the
1579      * foreground service, app should go back to cached state.
1580      * @throws Exception
1581      */
testCycleFgsTriangle()1582     public void testCycleFgsTriangle() throws Exception {
1583         ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo(
1584                 PACKAGE_NAME_APP1, 0);
1585         ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo(
1586                 PACKAGE_NAME_APP2, 0);
1587         ApplicationInfo app3Info = mContext.getPackageManager().getApplicationInfo(
1588                 PACKAGE_NAME_APP3, 0);
1589         WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid,
1590                 WAITFOR_MSEC);
1591         WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid,
1592                 WAITFOR_MSEC);
1593         WatchUidRunner uid3Watcher = new WatchUidRunner(mInstrumentation, app3Info.uid,
1594                 WAITFOR_MSEC);
1595 
1596         try {
1597             CommandReceiver.sendCommand(mContext,
1598                     CommandReceiver.COMMAND_START_FOREGROUND_SERVICE,
1599                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
1600             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1601 
1602             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1603                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null);
1604 
1605             uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1606 
1607             // Bind from 2 to 3
1608             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1609                     PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null);
1610             uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1611 
1612             // Create a cycle
1613             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1614                     PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null);
1615 
1616             try {
1617                 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
1618                         WatchUidRunner.STATE_CACHED_EMPTY);
1619                 fail("App3 should not be demoted to cached");
1620             } catch (IllegalStateException ise) {
1621                 // Didn't go to cached in spite of cycle. Good!
1622             }
1623 
1624             try {
1625                 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
1626                         WatchUidRunner.STATE_CACHED_EMPTY);
1627                 fail("App2 should not be demoted to cached");
1628             } catch (IllegalStateException ise) {
1629                 // Didn't go to cached in spite of cycle. Good!
1630             }
1631 
1632             try {
1633                 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
1634                         WatchUidRunner.STATE_CACHED_EMPTY);
1635                 fail("App1 should not be demoted to cached");
1636             } catch (IllegalStateException ise) {
1637                 // Didn't go to cached in spite of cycle. Good!
1638             }
1639 
1640             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1641                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null);
1642 
1643             uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1644             uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1645 
1646             // Clean up: unbind services to avoid from interferences with other tests
1647             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1648                 PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null);
1649             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1650                 PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null);
1651             // Stop the foreground service
1652             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE,
1653                 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
1654         } finally {
1655             uid1Watcher.finish();
1656             uid2Watcher.finish();
1657             uid3Watcher.finish();
1658         }
1659     }
1660 
1661     /**
1662      * Test a service binding cycle between three apps, with one of them also running a
1663      * foreground service. The other apps should also get an FGS proc state. On stopping the
1664      * foreground service, app should go back to cached state.
1665      * @throws Exception
1666      */
testCycleFgsTriangleBiDi()1667     public void testCycleFgsTriangleBiDi() throws Exception {
1668         ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo(
1669                 PACKAGE_NAME_APP1, 0);
1670         ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo(
1671                 PACKAGE_NAME_APP2, 0);
1672         ApplicationInfo app3Info = mContext.getPackageManager().getApplicationInfo(
1673                 PACKAGE_NAME_APP3, 0);
1674         WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid,
1675                 WAITFOR_MSEC);
1676         WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid,
1677                 WAITFOR_MSEC);
1678         WatchUidRunner uid3Watcher = new WatchUidRunner(mInstrumentation, app3Info.uid,
1679                 WAITFOR_MSEC);
1680 
1681         try {
1682             CommandReceiver.sendCommand(mContext,
1683                     CommandReceiver.COMMAND_START_FOREGROUND_SERVICE,
1684                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
1685             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1686 
1687             // Bind from 1 to 2, 1 to 3
1688             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1689                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null);
1690             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1691                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP3, 0, null);
1692 
1693             uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1694             uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1695 
1696             // Bind from 2 to 3, 3 to 2, 3 to 1
1697             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1698                     PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null);
1699             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1700                     PACKAGE_NAME_APP3, PACKAGE_NAME_APP2, 0, null);
1701             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1702                     PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null);
1703 
1704             try {
1705                 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
1706                         WatchUidRunner.STATE_CACHED_EMPTY);
1707                 fail("App3 should not be demoted to cached");
1708             } catch (IllegalStateException ise) {
1709                 // Didn't go to cached in spite of cycle. Good!
1710             }
1711 
1712             // Stop the foreground service
1713             CommandReceiver.sendCommand(mContext, CommandReceiver
1714                             .COMMAND_STOP_FOREGROUND_SERVICE,
1715                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
1716 
1717             // Check that the apps' proc state has fallen
1718             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1719             uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1720             uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1721 
1722             // Clean up: unbind services to avoid from interferences with other tests
1723             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1724                 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null);
1725             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1726                 PACKAGE_NAME_APP1, PACKAGE_NAME_APP3, 0, null);
1727             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1728                 PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null);
1729             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1730                 PACKAGE_NAME_APP3, PACKAGE_NAME_APP2, 0, null);
1731             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1732                 PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null);
1733         } finally {
1734             uid1Watcher.finish();
1735             uid2Watcher.finish();
1736             uid3Watcher.finish();
1737         }
1738     }
1739 
1740     /**
1741      * Test process states for foreground service with and without location type in the manifest.
1742      * When running a foreground service with location type, the process should go to
1743      * PROCESS_STATE_FOREGROUND_SERVICE_LOCATION.
1744      * @throws Exception
1745      */
testFgsLocation()1746     public void testFgsLocation() throws Exception {
1747         ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo(
1748                 PACKAGE_NAME_APP1, 0);
1749         WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid,
1750             WAITFOR_MSEC);
1751 
1752         try {
1753             // First start a foreground service
1754             CommandReceiver.sendCommand(mContext,
1755                     CommandReceiver.COMMAND_START_FOREGROUND_SERVICE,
1756                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
1757             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1758 
1759             // Try to elevate to foreground service location
1760             Bundle bundle = new Bundle();
1761             bundle.putInt(LocalForegroundServiceLocation.EXTRA_FOREGROUND_SERVICE_TYPE,
1762                     ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION);
1763             CommandReceiver.sendCommand(mContext,
1764                     CommandReceiver.COMMAND_START_FOREGROUND_SERVICE_LOCATION,
1765                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, bundle);
1766             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
1767                     WatchUidRunner.STATE_FG_SERVICE_LOCATION);
1768 
1769             // Back down to foreground service
1770             CommandReceiver.sendCommand(mContext,
1771                     CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE_LOCATION,
1772                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
1773             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1774 
1775             try {
1776                 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE,
1777                         WatchUidRunner.STATE_CACHED_EMPTY, WAIT_TIME);
1778                 fail("App1 should not be demoted to cached");
1779             } catch (IllegalStateException ise) {
1780             }
1781 
1782             // Remove foreground service as well
1783             CommandReceiver.sendCommand(mContext,
1784                     CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE,
1785                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null);
1786             uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1787 
1788         } finally {
1789             uid1Watcher.finish();
1790         }
1791     }
1792 
1793     /**
1794      * Test process states for foreground service binding to another app, with and without
1795      * BIND_INCLUDE_CAPABILITIES. Bound app should either go to FGS or FGSL, depending on the
1796      * flag.
1797      * @throws Exception
1798      */
testFgsLocationBind()1799     public void testFgsLocationBind() throws Exception {
1800         setupWatchers(3);
1801 
1802         try {
1803             // First start a foreground service
1804             CommandReceiver.sendCommand(mContext,
1805                     CommandReceiver.COMMAND_START_FOREGROUND_SERVICE,
1806                     mAppInfo[0].packageName, mAppInfo[0].packageName, 0, null);
1807             mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1808 
1809             // Try to elevate to foreground service location
1810             Bundle bundle = new Bundle();
1811             bundle.putInt(LocalForegroundServiceLocation.EXTRA_FOREGROUND_SERVICE_TYPE,
1812                     ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION);
1813             CommandReceiver.sendCommand(mContext,
1814                     CommandReceiver.COMMAND_START_FOREGROUND_SERVICE_LOCATION,
1815                     mAppInfo[0].packageName, mAppInfo[0].packageName, 0, bundle);
1816             // Verify moved to FGSL
1817             mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE,
1818                     WatchUidRunner.STATE_FG_SERVICE_LOCATION);
1819 
1820             // Bind App 0 -> App 1, verify doesn't include capabilities (only FGS, not FGSL)
1821             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1822                     mAppInfo[0].packageName, mAppInfo[1].packageName, 0, null);
1823             mWatchers[1].waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1824 
1825             // Bind App 0 -> App 2, include capabilities (FGSL)
1826             bundle = new Bundle();
1827             bundle.putInt(CommandReceiver.EXTRA_FLAGS, Context.BIND_INCLUDE_CAPABILITIES);
1828             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1829                     mAppInfo[0].packageName, mAppInfo[2].packageName, 0, bundle);
1830             mWatchers[2].waitFor(WatchUidRunner.CMD_PROCSTATE,
1831                     WatchUidRunner.STATE_FG_SERVICE_LOCATION);
1832 
1833             // Back down to foreground service
1834             CommandReceiver.sendCommand(mContext,
1835                     CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE_LOCATION,
1836                     mAppInfo[0].packageName, mAppInfo[0].packageName, 0, null);
1837             mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE);
1838 
1839             // Remove foreground service as well
1840             CommandReceiver.sendCommand(mContext,
1841                     CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE,
1842                     mAppInfo[0].packageName, mAppInfo[0].packageName, 0, null);
1843             mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY);
1844 
1845             // Clean up: unbind services to avoid from interferences with other tests
1846             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1847                 mAppInfo[0].packageName, mAppInfo[1].packageName, 0, null);
1848             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1849                 mAppInfo[0].packageName, mAppInfo[2].packageName, 0, bundle);
1850         } finally {
1851             shutdownWatchers();
1852         }
1853     }
1854 
1855     /**
1856      * Test process states for top app binding with and without BIND_INCLUDE_CAPABILITIES flag.
1857      * Bound app should be TOP w/flag and BTOP without flag.
1858      * @throws Exception
1859      */
testTopBind()1860     public void testTopBind() throws Exception {
1861         setupWatchers(2);
1862 
1863         Activity activity = null;
1864 
1865         try {
1866             // This will start an activity in App0
1867             activity = startSubActivity(ScreenOnActivity.class);
1868 
1869             // Bind Stub -> App 0, verify doesn't include capabilities (only BTOP, not TOP)
1870             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1871                     STUB_PACKAGE_NAME, mAppInfo[0].packageName, 0, null);
1872             mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_BOUND_TOP);
1873 
1874             // Bind Stub -> App 1, include capabilities (TOP)
1875             Bundle bundle = new Bundle();
1876             bundle.putInt(CommandReceiver.EXTRA_FLAGS, Context.BIND_INCLUDE_CAPABILITIES);
1877             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1878                     STUB_PACKAGE_NAME, mAppInfo[1].packageName, 0, bundle);
1879             mWatchers[1].waitFor(WatchUidRunner.CMD_PROCSTATE,
1880                     WatchUidRunner.STATE_TOP);
1881 
1882             // Clean up: unbind services to avoid from interferences with other tests
1883             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1884                 STUB_PACKAGE_NAME, mAppInfo[0].packageName, 0, null);
1885             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1886                 STUB_PACKAGE_NAME, mAppInfo[1].packageName, 0, bundle);
1887         } finally {
1888             shutdownWatchers();
1889             if (activity != null) {
1890                 activity.finish();
1891             }
1892         }
1893     }
1894 
startSubActivity(Class<T> activityClass)1895     private final <T extends Activity> Activity startSubActivity(Class<T> activityClass) {
1896         final Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(
1897                 0, new Intent());
1898         final Instrumentation.ActivityMonitor monitor = new Instrumentation.ActivityMonitor(
1899                 activityClass.getName(), result, false);
1900         mInstrumentation.addMonitor(monitor);
1901         launchActivity(STUB_PACKAGE_NAME, activityClass, null);
1902         return monitor.waitForActivity();
1903     }
1904 
testCycleTop()1905     public void testCycleTop() throws Exception {
1906         ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo(
1907                 PACKAGE_NAME_APP1, 0);
1908         ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo(
1909                 PACKAGE_NAME_APP2, 0);
1910         ApplicationInfo app3Info = mContext.getPackageManager().getApplicationInfo(
1911                 PACKAGE_NAME_APP3, 0);
1912 
1913         UidImportanceListener uid1Listener = new UidImportanceListener(mContext,
1914                 app1Info.uid, IMPORTANCE_VISIBLE,
1915                 WAITFOR_MSEC);
1916         uid1Listener.register();
1917 
1918         UidImportanceListener uid1ServiceListener = new UidImportanceListener(mContext,
1919                 app1Info.uid, IMPORTANCE_CACHED,
1920                 WAITFOR_MSEC);
1921         uid1ServiceListener.register();
1922 
1923         UidImportanceListener uid2Listener = new UidImportanceListener(mContext,
1924                 app2Info.uid, IMPORTANCE_VISIBLE,
1925                 WAITFOR_MSEC);
1926         uid2Listener.register();
1927 
1928         UidImportanceListener uid2ServiceListener = new UidImportanceListener(mContext,
1929                 app2Info.uid, IMPORTANCE_CACHED,
1930                 WAITFOR_MSEC);
1931         uid2ServiceListener.register();
1932 
1933         UidImportanceListener uid3Listener = new UidImportanceListener(mContext,
1934                 app3Info.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE,
1935                 WAITFOR_MSEC);
1936         uid3Listener.register();
1937 
1938         Activity activity = null;
1939 
1940         try {
1941             // Start an activity
1942             activity = startSubActivity(ScreenOnActivity.class);
1943 
1944             // Start a FGS in app2
1945             CommandReceiver.sendCommand(mContext,
1946                     CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, PACKAGE_NAME_APP2,
1947                     PACKAGE_NAME_APP2, 0, null);
1948 
1949             uid2Listener.waitForValue(
1950                     IMPORTANCE_FOREGROUND_SERVICE,
1951                     IMPORTANCE_FOREGROUND_SERVICE);
1952 
1953             // Bind from TOP to the service in app1
1954             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1955                     STUB_PACKAGE_NAME, PACKAGE_NAME_APP1, 0, null);
1956 
1957             uid1Listener.waitForValue(IMPORTANCE_FOREGROUND,
1958                     IMPORTANCE_FOREGROUND_SERVICE);
1959 
1960             // Bind from app1 to a service in app2
1961             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1962                     PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null);
1963 
1964             // Bind from app2 to a service in app3
1965             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1966                     PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null);
1967 
1968             uid3Listener.waitForValue(IMPORTANCE_FOREGROUND,
1969                     IMPORTANCE_FOREGROUND_SERVICE);
1970 
1971             // Create a cycle
1972             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE,
1973                     PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null);
1974 
1975             try {
1976                 uid3Listener.waitForValue(IMPORTANCE_CACHED,
1977                         IMPORTANCE_CACHED);
1978                 fail("App3 should not be demoted to cached, expecting FGS");
1979             } catch (IllegalStateException e) {
1980                 // Didn't go to cached in spite of cycle. Good!
1981             }
1982 
1983             // Unbind from the TOP app
1984             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
1985                     STUB_PACKAGE_NAME, PACKAGE_NAME_APP1, 0, null);
1986 
1987             // Check that the apps' proc state is FOREGROUND_SERVICE
1988             uid2Listener.waitForValue(
1989                     IMPORTANCE_FOREGROUND_SERVICE,
1990                     IMPORTANCE_FOREGROUND_SERVICE);
1991 
1992             // Stop the foreground service
1993             CommandReceiver.sendCommand(mContext, CommandReceiver
1994                             .COMMAND_STOP_FOREGROUND_SERVICE,
1995                     PACKAGE_NAME_APP2, PACKAGE_NAME_APP2, 0, null);
1996 
1997             // Check that the apps fall down to cached state
1998             uid1ServiceListener.waitForValue(
1999                     IMPORTANCE_CACHED,
2000                     IMPORTANCE_CACHED);
2001 
2002             uid2ServiceListener.waitForValue(
2003                     IMPORTANCE_CACHED,
2004                     IMPORTANCE_CACHED);
2005             uid3Listener.waitForValue(
2006                     IMPORTANCE_CACHED,
2007                     IMPORTANCE_CACHED);
2008 
2009             // Clean up: unbind services to avoid from interferences with other tests
2010             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
2011                 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null);
2012             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
2013                 PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null);
2014             CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE,
2015                 PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null);
2016         } finally {
2017             uid1Listener.unregister();
2018             uid1ServiceListener.unregister();
2019             uid2Listener.unregister();
2020             uid2ServiceListener.unregister();
2021             uid3Listener.unregister();
2022             if (activity != null) {
2023                 activity.finish();
2024             }
2025         }
2026     }
2027 }
2028