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