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