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