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 android.Manifest;
     20 import android.app.Activity;
     21 import android.app.ActivityManager;
     22 import android.app.Instrumentation;
     23 import android.app.KeyguardManager;
     24 import android.app.cts.android.app.cts.tools.ServiceConnectionHandler;
     25 import android.app.cts.android.app.cts.tools.ServiceProcessController;
     26 import android.app.cts.android.app.cts.tools.SyncOrderedBroadcast;
     27 import android.app.cts.android.app.cts.tools.UidImportanceListener;
     28 import android.app.cts.android.app.cts.tools.WaitForBroadcast;
     29 import android.app.cts.android.app.cts.tools.WatchUidRunner;
     30 import android.content.Context;
     31 import android.content.Intent;
     32 import android.content.pm.ApplicationInfo;
     33 import android.os.IBinder;
     34 import android.os.Parcel;
     35 import android.os.PowerManager;
     36 import android.os.RemoteException;
     37 import android.test.InstrumentationTestCase;
     38 
     39 import com.android.compatibility.common.util.SystemUtil;
     40 
     41 public class ActivityManagerProcessStateTest extends InstrumentationTestCase {
     42     private static final String STUB_PACKAGE_NAME = "android.app.stubs";
     43     private static final int WAIT_TIME = 2000;
     44     // A secondary test activity from another APK.
     45     static final String SIMPLE_PACKAGE_NAME = "com.android.cts.launcherapps.simpleapp";
     46     static final String SIMPLE_SERVICE = ".SimpleService";
     47     static final String SIMPLE_SERVICE2 = ".SimpleService2";
     48     static final String SIMPLE_RECEIVER_START_SERVICE = ".SimpleReceiverStartService";
     49     static final String SIMPLE_ACTIVITY_START_SERVICE = ".SimpleActivityStartService";
     50     public static String ACTION_SIMPLE_ACTIVITY_START_SERVICE_RESULT =
     51             "com.android.cts.launcherapps.simpleapp.SimpleActivityStartService.RESULT";
     52 
     53     private Context mContext;
     54     private Instrumentation mInstrumentation;
     55     private Intent mServiceIntent;
     56     private Intent mService2Intent;
     57     private Intent mAllProcesses[];
     58 
     59     @Override
     60     protected void setUp() throws Exception {
     61         super.setUp();
     62         mInstrumentation = getInstrumentation();
     63         mContext = mInstrumentation.getContext();
     64         mServiceIntent = new Intent();
     65         mServiceIntent.setClassName(SIMPLE_PACKAGE_NAME, SIMPLE_PACKAGE_NAME + SIMPLE_SERVICE);
     66         mService2Intent = new Intent();
     67         mService2Intent.setClassName(SIMPLE_PACKAGE_NAME, SIMPLE_PACKAGE_NAME + SIMPLE_SERVICE2);
     68         mAllProcesses = new Intent[2];
     69         mAllProcesses[0] = mServiceIntent;
     70         mAllProcesses[1] = mService2Intent;
     71         mContext.stopService(mServiceIntent);
     72         mContext.stopService(mService2Intent);
     73     }
     74 
     75     @Override
     76     protected void tearDown() throws Exception {
     77         super.tearDown();
     78     }
     79 
     80     /**
     81      * Test basic state changes as processes go up and down due to services running in them.
     82      */
     83     public void testUidImportanceListener() throws Exception {
     84         final Parcel data = Parcel.obtain();
     85         ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext, mServiceIntent);
     86         ServiceConnectionHandler conn2 = new ServiceConnectionHandler(mContext, mService2Intent);
     87 
     88         ActivityManager am = mContext.getSystemService(ActivityManager.class);
     89 
     90         ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo(
     91                 SIMPLE_PACKAGE_NAME, 0);
     92         UidImportanceListener uidForegroundListener = new UidImportanceListener(appInfo.uid);
     93 
     94         String cmd = "pm revoke " + STUB_PACKAGE_NAME + " "
     95                 + Manifest.permission.PACKAGE_USAGE_STATS;
     96         String result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
     97         /*
     98         Log.d("XXXX", "Invoke: " + cmd);
     99         Log.d("XXXX", "Result: " + result);
    100         */
    101         boolean gotException = false;
    102         try {
    103             am.addOnUidImportanceListener(uidForegroundListener,
    104                     ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE);
    105         } catch (SecurityException e) {
    106             gotException = true;
    107         }
    108         assertTrue("Expected SecurityException thrown", gotException);
    109 
    110         cmd = "pm grant " + STUB_PACKAGE_NAME + " "
    111                 + Manifest.permission.PACKAGE_USAGE_STATS;
    112         result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
    113         /*
    114         Log.d("XXXX", "Invoke: " + cmd);
    115         Log.d("XXXX", "Result: " + result);
    116         Log.d("XXXX", SystemUtil.runShellCommand(getInstrumentation(), "dumpsys package "
    117                 + STUB_PACKAGE_NAME));
    118         */
    119         am.addOnUidImportanceListener(uidForegroundListener,
    120                 ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE);
    121 
    122         UidImportanceListener uidGoneListener = new UidImportanceListener(appInfo.uid);
    123         am.addOnUidImportanceListener(uidGoneListener,
    124                 ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED);
    125 
    126         WatchUidRunner uidWatcher = new WatchUidRunner(getInstrumentation(), appInfo.uid);
    127 
    128         try {
    129             // First kill the processes to start out in a stable state.
    130             conn.bind(WAIT_TIME);
    131             conn2.bind(WAIT_TIME);
    132             IBinder service1 = conn.getServiceIBinder();
    133             IBinder service2 = conn2.getServiceIBinder();
    134             conn.unbind(WAIT_TIME);
    135             conn2.unbind(WAIT_TIME);
    136             try {
    137                 service1.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0);
    138             } catch (RemoteException e) {
    139             }
    140             try {
    141                 service2.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0);
    142             } catch (RemoteException e) {
    143             }
    144             service1 = service2 = null;
    145 
    146             // Wait for uid's processes to go away.
    147             uidGoneListener.waitForValue(ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE,
    148                     ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE, WAIT_TIME);
    149             assertEquals(ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE,
    150                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
    151 
    152             // And wait for the uid report to be gone.
    153             uidWatcher.waitFor(WatchUidRunner.CMD_GONE, null, WAIT_TIME);
    154 
    155             // Now bind and see if we get told about the uid coming in to the foreground.
    156             conn.bind(WAIT_TIME);
    157             uidForegroundListener.waitForValue(ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND,
    158                     ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE, WAIT_TIME);
    159             assertEquals(ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE,
    160                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
    161 
    162             // Also make sure the uid state reports are as expected.  Wait for active because
    163             // there may be some intermediate states as the process comes up.
    164             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null, WAIT_TIME);
    165             uidWatcher.expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
    166             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "FGS", WAIT_TIME);
    167 
    168             // Pull out the service IBinder for a kludy hack...
    169             IBinder service = conn.getServiceIBinder();
    170 
    171             // Now unbind and see if we get told about it going to the background.
    172             conn.unbind(WAIT_TIME);
    173             uidForegroundListener.waitForValue(ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED,
    174                     ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED, WAIT_TIME);
    175             assertEquals(ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED,
    176                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
    177 
    178             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null, WAIT_TIME);
    179             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
    180 
    181             // Now kill the process and see if we are told about it being gone.
    182             try {
    183                 service.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0);
    184             } catch (RemoteException e) {
    185                 // It is okay if it is already gone for some reason.
    186             }
    187 
    188             uidGoneListener.waitForValue(ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE,
    189                     ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE, WAIT_TIME);
    190             assertEquals(ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE,
    191                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
    192 
    193             uidWatcher.expect(WatchUidRunner.CMD_IDLE, null, WAIT_TIME);
    194             uidWatcher.expect(WatchUidRunner.CMD_GONE, null, WAIT_TIME);
    195 
    196             // Now we are going to try different combinations of binding to two processes to
    197             // see if they are correctly combined together for the app.
    198 
    199             // Bring up both services.
    200             conn.bind(WAIT_TIME);
    201             conn2.bind(WAIT_TIME);
    202             uidForegroundListener.waitForValue(ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND,
    203                     ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE, WAIT_TIME);
    204             assertEquals(ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE,
    205                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
    206 
    207             // Also make sure the uid state reports are as expected.
    208             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null, WAIT_TIME);
    209             uidWatcher.expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
    210             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "FGS", WAIT_TIME);
    211 
    212             // Bring down one service, app state should remain foreground.
    213             conn2.unbind(WAIT_TIME);
    214             assertEquals(ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE,
    215                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
    216 
    217             // Bring down other service, app state should now be cached.  (If the processes both
    218             // actually get killed immediately, this is also not a correctly behaving system.)
    219             conn.unbind(WAIT_TIME);
    220             uidGoneListener.waitForValue(ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED,
    221                     ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED, WAIT_TIME);
    222             assertEquals(ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED,
    223                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
    224 
    225             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null, WAIT_TIME);
    226             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
    227 
    228             // Bring up one service, this should be sufficient to become foreground.
    229             conn2.bind(WAIT_TIME);
    230             uidForegroundListener.waitForValue(ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND,
    231                     ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE, WAIT_TIME);
    232             assertEquals(ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE,
    233                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
    234 
    235             uidWatcher.expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
    236             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "FGS", WAIT_TIME);
    237 
    238             // Bring up other service, should remain foreground.
    239             conn.bind(WAIT_TIME);
    240             assertEquals(ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE,
    241                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
    242 
    243             // Bring down one service, should remain foreground.
    244             conn.unbind(WAIT_TIME);
    245             assertEquals(ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE,
    246                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
    247 
    248             // And bringing down other service should put us back to cached.
    249             conn2.unbind(WAIT_TIME);
    250             uidGoneListener.waitForValue(ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED,
    251                     ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED, WAIT_TIME);
    252             assertEquals(ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED,
    253                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
    254 
    255             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null, WAIT_TIME);
    256             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
    257         } finally {
    258             data.recycle();
    259 
    260             uidWatcher.finish();
    261 
    262             am.removeOnUidImportanceListener(uidForegroundListener);
    263             am.removeOnUidImportanceListener(uidGoneListener);
    264         }
    265     }
    266 
    267     /**
    268      * Test that background check correctly prevents idle services from running but allows
    269      * whitelisted apps to bypass the check.
    270      */
    271     public void testBackgroundCheckService() throws Exception {
    272         final Parcel data = Parcel.obtain();
    273         Intent serviceIntent = new Intent();
    274         serviceIntent.setClassName(SIMPLE_PACKAGE_NAME,
    275                 SIMPLE_PACKAGE_NAME + SIMPLE_SERVICE);
    276         ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext, serviceIntent);
    277 
    278         ActivityManager am = mContext.getSystemService(ActivityManager.class);
    279 
    280         String cmd = "pm grant " + STUB_PACKAGE_NAME + " "
    281                 + Manifest.permission.PACKAGE_USAGE_STATS;
    282         String result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
    283         /*
    284         Log.d("XXXX", "Invoke: " + cmd);
    285         Log.d("XXXX", "Result: " + result);
    286         Log.d("XXXX", SystemUtil.runShellCommand(getInstrumentation(), "dumpsys package "
    287                 + STUB_PACKAGE_NAME));
    288         */
    289 
    290         ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo(
    291                 SIMPLE_PACKAGE_NAME, 0);
    292 
    293         UidImportanceListener uidForegroundListener = new UidImportanceListener(appInfo.uid);
    294         am.addOnUidImportanceListener(uidForegroundListener,
    295                 ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE);
    296         UidImportanceListener uidGoneListener = new UidImportanceListener(appInfo.uid);
    297         am.addOnUidImportanceListener(uidGoneListener,
    298                 ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY);
    299 
    300         WatchUidRunner uidWatcher = new WatchUidRunner(getInstrumentation(), appInfo.uid);
    301 
    302         // First kill the process to start out in a stable state.
    303         mContext.stopService(serviceIntent);
    304         conn.bind(WAIT_TIME);
    305         IBinder service = conn.getServiceIBinder();
    306         conn.unbind(WAIT_TIME);
    307         try {
    308             service.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0);
    309         } catch (RemoteException e) {
    310         }
    311         service = null;
    312 
    313         // Wait for uid's process to go away.
    314         uidGoneListener.waitForValue(ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE,
    315                 ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE, WAIT_TIME);
    316         assertEquals(ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE,
    317                 am.getPackageImportance(SIMPLE_PACKAGE_NAME));
    318 
    319         // And wait for the uid report to be gone.
    320         uidWatcher.waitFor(WatchUidRunner.CMD_GONE, null, WAIT_TIME);
    321 
    322         cmd = "appops set " + SIMPLE_PACKAGE_NAME + " RUN_IN_BACKGROUND deny";
    323         result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
    324 
    325         // This is a side-effect of the app op command.
    326         uidWatcher.expect(WatchUidRunner.CMD_IDLE, null, WAIT_TIME);
    327         uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "NONE", WAIT_TIME);
    328 
    329         // We don't want to wait for the uid to actually go idle, we can force it now.
    330         cmd = "am make-uid-idle " + SIMPLE_PACKAGE_NAME;
    331         result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
    332 
    333         // Make sure app is not yet on whitelist
    334         cmd = "cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME;
    335         result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
    336 
    337         // We will use this to monitor when the service is running.
    338         conn.startMonitoring();
    339 
    340         try {
    341             // Try starting the service.  Should fail!
    342             boolean failed = false;
    343             try {
    344                 mContext.startService(serviceIntent);
    345             } catch (IllegalStateException e) {
    346                 failed = true;
    347             }
    348             if (!failed) {
    349                 fail("Service was allowed to start while in the background");
    350             }
    351 
    352             // Put app on temporary whitelist to see if this allows the service start.
    353             cmd = "cmd deviceidle tempwhitelist -d 2000 " + SIMPLE_PACKAGE_NAME;
    354             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
    355 
    356             // Try starting the service now that the app is whitelisted...  should work!
    357             mContext.startService(serviceIntent);
    358             conn.waitForConnect(WAIT_TIME);
    359 
    360             // Also make sure the uid state reports are as expected.
    361             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null, WAIT_TIME);
    362             uidWatcher.expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
    363             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "SVC", WAIT_TIME);
    364 
    365             // Good, now stop the service and give enough time to get off the temp whitelist.
    366             mContext.stopService(serviceIntent);
    367             conn.waitForDisconnect(WAIT_TIME);
    368 
    369             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null, WAIT_TIME);
    370             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
    371 
    372             Thread.sleep(3000);
    373 
    374             // Going off the temp whitelist causes a spurious proc state report...  that's
    375             // not ideal, but okay.
    376             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
    377 
    378             // We don't want to wait for the uid to actually go idle, we can force it now.
    379             cmd = "am make-uid-idle " + SIMPLE_PACKAGE_NAME;
    380             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
    381 
    382             uidWatcher.expect(WatchUidRunner.CMD_IDLE, null, WAIT_TIME);
    383             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
    384 
    385             // Now that we should be off the temp whitelist, make sure we again can't start.
    386             failed = false;
    387             try {
    388                 mContext.startService(serviceIntent);
    389             } catch (IllegalStateException e) {
    390                 failed = true;
    391             }
    392             if (!failed) {
    393                 fail("Service was allowed to start while in the background");
    394             }
    395 
    396             // Now put app on whitelist, should allow service to run.
    397             cmd = "cmd deviceidle whitelist +" + SIMPLE_PACKAGE_NAME;
    398             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
    399 
    400             // Try starting the service now that the app is whitelisted...  should work!
    401             mContext.startService(serviceIntent);
    402             conn.waitForConnect(WAIT_TIME);
    403 
    404             uidWatcher.expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
    405             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "SVC", WAIT_TIME);
    406 
    407             // Okay, bring down the service.
    408             mContext.stopService(serviceIntent);
    409             conn.waitForDisconnect(WAIT_TIME);
    410 
    411             uidWatcher.expect(WatchUidRunner.CMD_CACHED, null, WAIT_TIME);
    412             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
    413 
    414         } finally {
    415             mContext.stopService(serviceIntent);
    416             conn.stopMonitoring();
    417 
    418             uidWatcher.finish();
    419 
    420             cmd = "appops set " + SIMPLE_PACKAGE_NAME + " RUN_IN_BACKGROUND allow";
    421             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
    422             cmd = "cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME;
    423             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
    424 
    425             am.removeOnUidImportanceListener(uidGoneListener);
    426             am.removeOnUidImportanceListener(uidForegroundListener);
    427 
    428             data.recycle();
    429         }
    430     }
    431 
    432     /**
    433      * Test that background check behaves correctly after a process is no longer foreground:
    434      * first allowing a service to be started, then stopped by the system when idle.
    435      */
    436     public void testBackgroundCheckStopsService() throws Exception {
    437         final Parcel data = Parcel.obtain();
    438         ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext, mServiceIntent);
    439         ServiceConnectionHandler conn2 = new ServiceConnectionHandler(mContext, mService2Intent);
    440 
    441         ActivityManager am = mContext.getSystemService(ActivityManager.class);
    442 
    443         String cmd = "pm grant " + STUB_PACKAGE_NAME + " "
    444                 + Manifest.permission.PACKAGE_USAGE_STATS;
    445         String result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
    446         /*
    447         Log.d("XXXX", "Invoke: " + cmd);
    448         Log.d("XXXX", "Result: " + result);
    449         Log.d("XXXX", SystemUtil.runShellCommand(getInstrumentation(), "dumpsys package "
    450                 + STUB_PACKAGE_NAME));
    451         */
    452 
    453         ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo(
    454                 SIMPLE_PACKAGE_NAME, 0);
    455 
    456         UidImportanceListener uidServiceListener = new UidImportanceListener(appInfo.uid);
    457         am.addOnUidImportanceListener(uidServiceListener,
    458                 ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE);
    459         UidImportanceListener uidGoneListener = new UidImportanceListener(appInfo.uid);
    460         am.addOnUidImportanceListener(uidGoneListener,
    461                 ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED);
    462 
    463         WatchUidRunner uidWatcher = new WatchUidRunner(getInstrumentation(), appInfo.uid);
    464 
    465         // First kill the process to start out in a stable state.
    466         mContext.stopService(mServiceIntent);
    467         mContext.stopService(mService2Intent);
    468         conn.bind(WAIT_TIME);
    469         conn2.bind(WAIT_TIME);
    470         IBinder service = conn.getServiceIBinder();
    471         IBinder service2 = conn2.getServiceIBinder();
    472         conn.unbind(WAIT_TIME);
    473         conn2.unbind(WAIT_TIME);
    474         try {
    475             service.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0);
    476         } catch (RemoteException e) {
    477         }
    478         try {
    479             service2.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0);
    480         } catch (RemoteException e) {
    481         }
    482         service = service2 = null;
    483 
    484         // Wait for uid's process to go away.
    485         uidGoneListener.waitForValue(ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE,
    486                 ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE, WAIT_TIME);
    487         assertEquals(ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE,
    488                 am.getPackageImportance(SIMPLE_PACKAGE_NAME));
    489 
    490         // And wait for the uid report to be gone.
    491         uidWatcher.waitFor(WatchUidRunner.CMD_GONE, null, WAIT_TIME);
    492 
    493         cmd = "appops set " + SIMPLE_PACKAGE_NAME + " RUN_IN_BACKGROUND deny";
    494         result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
    495 
    496         // This is a side-effect of the app op command.
    497         uidWatcher.expect(WatchUidRunner.CMD_IDLE, null, WAIT_TIME);
    498         uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "NONE", WAIT_TIME);
    499 
    500         // We don't want to wait for the uid to actually go idle, we can force it now.
    501         cmd = "am make-uid-idle " + SIMPLE_PACKAGE_NAME;
    502         result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
    503 
    504         // Make sure app is not yet on whitelist
    505         cmd = "cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME;
    506         result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
    507 
    508         // We will use this to monitor when the service is running.
    509         conn.startMonitoring();
    510 
    511         try {
    512             // Try starting the service.  Should fail!
    513             boolean failed = false;
    514             try {
    515                 mContext.startService(mServiceIntent);
    516             } catch (IllegalStateException e) {
    517                 failed = true;
    518             }
    519             if (!failed) {
    520                 fail("Service was allowed to start while in the background");
    521             }
    522 
    523             // First poke the process into the foreground, so we can avoid background check.
    524             conn2.bind(WAIT_TIME);
    525             conn2.waitForConnect(WAIT_TIME);
    526 
    527             // Wait for process state to reflect running service.
    528             uidServiceListener.waitForValue(
    529                     ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE,
    530                     ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE, WAIT_TIME);
    531             assertEquals(ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE,
    532                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
    533 
    534             // Also make sure the uid state reports are as expected.
    535             uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null, WAIT_TIME);
    536             uidWatcher.expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
    537             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "FGS", WAIT_TIME);
    538 
    539             conn2.unbind(WAIT_TIME);
    540 
    541             // Wait for process to recover back down to being cached.
    542             uidServiceListener.waitForValue(ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED,
    543                     ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE, WAIT_TIME);
    544             assertEquals(ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED,
    545                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
    546 
    547             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null, WAIT_TIME);
    548             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
    549 
    550             // Try starting the service now that the app is waiting to idle...  should work!
    551             mContext.startService(mServiceIntent);
    552             conn.waitForConnect(WAIT_TIME);
    553 
    554             uidWatcher.expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
    555             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "SVC", WAIT_TIME);
    556 
    557             // And also start the second service.
    558             conn2.startMonitoring();
    559             mContext.startService(mService2Intent);
    560             conn2.waitForConnect(WAIT_TIME);
    561 
    562             // Force app to go idle now
    563             cmd = "am make-uid-idle " + SIMPLE_PACKAGE_NAME;
    564             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
    565 
    566             // Wait for services to be stopped by system.
    567             uidServiceListener.waitForValue(ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED,
    568                     ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE, WAIT_TIME);
    569             assertEquals(ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED,
    570                     am.getPackageImportance(SIMPLE_PACKAGE_NAME));
    571 
    572             // And service should be stopped by system, so just make sure it is disconnected.
    573             conn.waitForDisconnect(WAIT_TIME);
    574             conn2.waitForDisconnect(WAIT_TIME);
    575 
    576             uidWatcher.expect(WatchUidRunner.CMD_IDLE, null, WAIT_TIME);
    577             // There may be a transient 'SVC' proc state here.
    578             uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null, WAIT_TIME);
    579             uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
    580 
    581         } finally {
    582             mContext.stopService(mServiceIntent);
    583             mContext.stopService(mService2Intent);
    584             conn.cleanup(WAIT_TIME);
    585             conn2.cleanup(WAIT_TIME);
    586 
    587             uidWatcher.finish();
    588 
    589             cmd = "appops set " + SIMPLE_PACKAGE_NAME + " RUN_IN_BACKGROUND allow";
    590             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
    591             cmd = "cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME;
    592             result = SystemUtil.runShellCommand(getInstrumentation(), cmd);
    593 
    594             am.removeOnUidImportanceListener(uidGoneListener);
    595             am.removeOnUidImportanceListener(uidServiceListener);
    596 
    597             data.recycle();
    598         }
    599     }
    600 
    601     /**
    602      * Test the background check doesn't allow services to be started from broadcasts except
    603      * when in the correct states.
    604      */
    605     public void testBackgroundCheckBroadcastService() throws Exception {
    606         final Intent broadcastIntent = new Intent();
    607         broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
    608         broadcastIntent.setClassName(SIMPLE_PACKAGE_NAME,
    609                 SIMPLE_PACKAGE_NAME + SIMPLE_RECEIVER_START_SERVICE);
    610 
    611         final ServiceProcessController controller = new ServiceProcessController(mContext,
    612                 getInstrumentation(), STUB_PACKAGE_NAME, mAllProcesses);
    613         final ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext,
    614                 mServiceIntent);
    615 
    616         try {
    617             // First kill the process to start out in a stable state.
    618             controller.ensureProcessGone(WAIT_TIME);
    619 
    620             // Do initial setup.
    621             controller.denyBackgroundOp(WAIT_TIME);
    622             controller.makeUidIdle();
    623             controller.removeFromWhitelist();
    624 
    625             // We will use this to monitor when the service is running.
    626             conn.startMonitoring();
    627 
    628             // Try sending broadcast to start the service.  Should fail!
    629             SyncOrderedBroadcast br = new SyncOrderedBroadcast();
    630             broadcastIntent.putExtra("service", mServiceIntent);
    631             br.sendAndWait(mContext, broadcastIntent, Activity.RESULT_OK, null, null, WAIT_TIME);
    632             int brCode = br.getReceivedCode();
    633             if (brCode != Activity.RESULT_CANCELED) {
    634                 fail("Didn't fail starting service, result=" + brCode);
    635             }
    636 
    637             // Track the uid proc state changes from the broadcast (but not service execution)
    638             controller.getUidWatcher().waitFor(WatchUidRunner.CMD_IDLE, null, WAIT_TIME);
    639             controller.getUidWatcher().expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
    640             controller.getUidWatcher().expect(WatchUidRunner.CMD_PROCSTATE, "RCVR", WAIT_TIME);
    641             controller.getUidWatcher().expect(WatchUidRunner.CMD_CACHED, null, WAIT_TIME);
    642             controller.getUidWatcher().expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
    643 
    644             // Put app on temporary whitelist to see if this allows the service start.
    645             controller.tempWhitelist(2000);
    646 
    647             // Being on the whitelist means the uid is now active.
    648             controller.getUidWatcher().expect(WatchUidRunner.CMD_ACTIVE, null, WAIT_TIME);
    649             controller.getUidWatcher().expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
    650 
    651             // Try starting the service now that the app is whitelisted...  should work!
    652             br.sendAndWait(mContext, broadcastIntent, Activity.RESULT_OK, null, null, WAIT_TIME);
    653             brCode = br.getReceivedCode();
    654             if (brCode != Activity.RESULT_FIRST_USER) {
    655                 fail("Failed starting service, result=" + brCode);
    656             }
    657             conn.waitForConnect(WAIT_TIME);
    658 
    659             // Also make sure the uid state reports are as expected.
    660             controller.getUidWatcher().expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
    661             // We are going to wait until 'SVC', because we may see an intermediate 'RCVR'
    662             // proc state depending on timing.
    663             controller.getUidWatcher().waitFor(WatchUidRunner.CMD_PROCSTATE, "SVC", WAIT_TIME);
    664 
    665             // Good, now stop the service and give enough time to get off the temp whitelist.
    666             mContext.stopService(mServiceIntent);
    667             conn.waitForDisconnect(WAIT_TIME);
    668 
    669             controller.getUidWatcher().expect(WatchUidRunner.CMD_CACHED, null, WAIT_TIME);
    670             controller.getUidWatcher().expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
    671 
    672             Thread.sleep(3000);
    673 
    674             // Going off the temp whitelist causes a spurious proc state report...  that's
    675             // not ideal, but okay.
    676             controller.getUidWatcher().expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
    677 
    678             // We don't want to wait for the uid to actually go idle, we can force it now.
    679             controller.makeUidIdle();
    680 
    681             controller.getUidWatcher().expect(WatchUidRunner.CMD_IDLE, null, WAIT_TIME);
    682 
    683             // Make sure the process is gone so we start over fresh.
    684             controller.ensureProcessGone(WAIT_TIME);
    685 
    686             // Now that we should be off the temp whitelist, make sure we again can't start.
    687             br.sendAndWait(mContext, broadcastIntent, Activity.RESULT_OK, null, null, WAIT_TIME);
    688             brCode = br.getReceivedCode();
    689             if (brCode != Activity.RESULT_CANCELED) {
    690                 fail("Didn't fail starting service, result=" + brCode);
    691             }
    692 
    693             // Track the uid proc state changes from the broadcast (but not service execution)
    694             controller.getUidWatcher().waitFor(WatchUidRunner.CMD_IDLE, null, WAIT_TIME);
    695             // There could be a transient 'cached' state here before 'uncached' if uid state
    696             // changes are dispatched before receiver is started.
    697             controller.getUidWatcher().waitFor(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
    698             controller.getUidWatcher().expect(WatchUidRunner.CMD_PROCSTATE, "RCVR", WAIT_TIME);
    699             controller.getUidWatcher().expect(WatchUidRunner.CMD_CACHED, null, WAIT_TIME);
    700             controller.getUidWatcher().expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
    701 
    702             // Now put app on whitelist, should allow service to run.
    703             controller.addToWhitelist();
    704 
    705             // Try starting the service now that the app is whitelisted...  should work!
    706             br.sendAndWait(mContext, broadcastIntent, Activity.RESULT_OK, null, null, WAIT_TIME);
    707             brCode = br.getReceivedCode();
    708             if (brCode != Activity.RESULT_FIRST_USER) {
    709                 fail("Failed starting service, result=" + brCode);
    710             }
    711             conn.waitForConnect(WAIT_TIME);
    712 
    713             // Also make sure the uid state reports are as expected.
    714             controller.getUidWatcher().expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
    715             controller.getUidWatcher().waitFor(WatchUidRunner.CMD_PROCSTATE, "SVC", WAIT_TIME);
    716 
    717             // Okay, bring down the service.
    718             mContext.stopService(mServiceIntent);
    719             conn.waitForDisconnect(WAIT_TIME);
    720 
    721             controller.getUidWatcher().expect(WatchUidRunner.CMD_CACHED, null, WAIT_TIME);
    722             controller.getUidWatcher().expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
    723 
    724         } finally {
    725             mContext.stopService(mServiceIntent);
    726             conn.stopMonitoringIfNeeded();
    727             controller.cleanup();
    728         }
    729     }
    730 
    731 
    732     /**
    733      * Test that background check does allow services to be started from activities.
    734      */
    735     public void testBackgroundCheckActivityService() throws Exception {
    736         final Intent activityIntent = new Intent();
    737         activityIntent.setClassName(SIMPLE_PACKAGE_NAME,
    738                 SIMPLE_PACKAGE_NAME + SIMPLE_ACTIVITY_START_SERVICE);
    739 
    740         final ServiceProcessController controller = new ServiceProcessController(mContext,
    741                 getInstrumentation(), STUB_PACKAGE_NAME, mAllProcesses);
    742         final ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext,
    743                 mServiceIntent);
    744 
    745         try {
    746             // First kill the process to start out in a stable state.
    747             controller.ensureProcessGone(WAIT_TIME);
    748 
    749             // Do initial setup.
    750             controller.denyBackgroundOp(WAIT_TIME);
    751             controller.makeUidIdle();
    752             controller.removeFromWhitelist();
    753 
    754             // We will use this to monitor when the service is running.
    755             conn.startMonitoring();
    756 
    757             // Try starting activity that will start the service.  This should be okay.
    758             WaitForBroadcast waiter = new WaitForBroadcast(mInstrumentation.getTargetContext());
    759             waiter.prepare(ACTION_SIMPLE_ACTIVITY_START_SERVICE_RESULT);
    760             activityIntent.putExtra("service", mServiceIntent);
    761             mContext.startActivity(activityIntent);
    762             Intent resultIntent = waiter.doWait(WAIT_TIME);
    763             int brCode = resultIntent.getIntExtra("result", Activity.RESULT_CANCELED);
    764             if (brCode != Activity.RESULT_FIRST_USER) {
    765                 fail("Failed starting service, result=" + brCode);
    766             }
    767             conn.waitForConnect(WAIT_TIME);
    768 
    769             final String expectedActivityState = (isScreenInteractive() && !isKeyguardLocked())
    770                     ? "TOP" : "TPSL";
    771             // Also make sure the uid state reports are as expected.
    772             controller.getUidWatcher().waitFor(WatchUidRunner.CMD_ACTIVE, null, WAIT_TIME);
    773             controller.getUidWatcher().expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
    774             controller.getUidWatcher().expect(WatchUidRunner.CMD_PROCSTATE,
    775                     expectedActivityState, WAIT_TIME);
    776             controller.getUidWatcher().expect(WatchUidRunner.CMD_PROCSTATE, "SVC", WAIT_TIME);
    777 
    778             // Okay, bring down the service.
    779             mContext.stopService(mServiceIntent);
    780             conn.waitForDisconnect(WAIT_TIME);
    781 
    782             controller.getUidWatcher().expect(WatchUidRunner.CMD_CACHED, null, WAIT_TIME);
    783             controller.getUidWatcher().expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
    784 
    785             // App isn't yet idle, so we should be able to start the service again.
    786             mContext.startService(mServiceIntent);
    787             conn.waitForConnect(WAIT_TIME);
    788             controller.getUidWatcher().expect(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME);
    789             controller.getUidWatcher().expect(WatchUidRunner.CMD_PROCSTATE, "SVC", WAIT_TIME);
    790 
    791             // And now fast-forward to the app going idle, service should be stopped.
    792             controller.makeUidIdle();
    793             controller.getUidWatcher().waitFor(WatchUidRunner.CMD_IDLE, null, WAIT_TIME);
    794 
    795             conn.waitForDisconnect(WAIT_TIME);
    796             controller.getUidWatcher().waitFor(WatchUidRunner.CMD_CACHED, null, WAIT_TIME);
    797             controller.getUidWatcher().expect(WatchUidRunner.CMD_PROCSTATE, "CEM", WAIT_TIME);
    798 
    799             // No longer should be able to start service.
    800             boolean failed = false;
    801             try {
    802                 mContext.startService(mServiceIntent);
    803             } catch (IllegalStateException e) {
    804                 failed = true;
    805             }
    806             if (!failed) {
    807                 fail("Service was allowed to start while in the background");
    808             }
    809 
    810         } finally {
    811             mContext.stopService(mServiceIntent);
    812             conn.stopMonitoringIfNeeded();
    813             controller.cleanup();
    814         }
    815     }
    816 
    817     private boolean isScreenInteractive() {
    818         final PowerManager powerManager =
    819                 (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
    820         return powerManager.isInteractive();
    821     }
    822 
    823     private boolean isKeyguardLocked() {
    824         final KeyguardManager keyguardManager =
    825                 (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
    826         return keyguardManager.isKeyguardLocked();
    827     }
    828 }
    829