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.PROCESS_CAPABILITY_ALL; 20 import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL_IMPLICIT; 21 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION; 22 import static android.app.ActivityManager.PROCESS_CAPABILITY_NETWORK; 23 import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE; 24 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED; 25 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 26 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE; 27 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE; 28 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; 29 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; 30 import static android.app.stubs.LocalForegroundService.ACTION_START_FGS_RESULT; 31 import static android.app.stubs.LocalForegroundServiceSticky.ACTION_RESTART_FGS_STICKY_RESULT; 32 33 import static junit.framework.Assert.assertEquals; 34 import static junit.framework.Assert.assertTrue; 35 import static junit.framework.Assert.fail; 36 37 import android.accessibilityservice.AccessibilityService; 38 import android.app.Activity; 39 import android.app.ActivityManager; 40 import android.app.ActivityOptions; 41 import android.app.AppOpsManager; 42 import android.app.Instrumentation; 43 import android.app.Service; 44 import android.app.cts.android.app.cts.tools.ServiceConnectionHandler; 45 import android.app.cts.android.app.cts.tools.ServiceProcessController; 46 import android.app.cts.android.app.cts.tools.SyncOrderedBroadcast; 47 import android.app.cts.android.app.cts.tools.UidImportanceListener; 48 import android.app.cts.android.app.cts.tools.WaitForBroadcast; 49 import android.app.cts.android.app.cts.tools.WatchUidRunner; 50 import android.app.stubs.CommandReceiver; 51 import android.app.stubs.LocalForegroundServiceLocation; 52 import android.app.stubs.LocalForegroundServiceSticky; 53 import android.app.stubs.ScreenOnActivity; 54 import android.content.BroadcastReceiver; 55 import android.content.ComponentName; 56 import android.content.Context; 57 import android.content.Intent; 58 import android.content.pm.ApplicationInfo; 59 import android.content.pm.PackageManager; 60 import android.content.pm.ServiceInfo; 61 import android.os.Build; 62 import android.os.Bundle; 63 import android.os.IBinder; 64 import android.os.Parcel; 65 import android.os.RemoteException; 66 import android.os.SystemClock; 67 import android.os.UserHandle; 68 import android.permission.cts.PermissionUtils; 69 import android.platform.test.annotations.Presubmit; 70 import android.server.wm.WindowManagerStateHelper; 71 import android.support.test.uiautomator.BySelector; 72 import android.support.test.uiautomator.UiDevice; 73 import android.support.test.uiautomator.UiSelector; 74 import android.util.Log; 75 76 import androidx.test.ext.junit.runners.AndroidJUnit4; 77 import androidx.test.platform.app.InstrumentationRegistry; 78 79 import com.android.compatibility.common.util.AmMonitor; 80 import com.android.compatibility.common.util.SystemUtil; 81 82 import org.junit.After; 83 import org.junit.Before; 84 import org.junit.Test; 85 import org.junit.runner.RunWith; 86 87 import java.util.ArrayList; 88 import java.util.Arrays; 89 import java.util.List; 90 import java.util.concurrent.CountDownLatch; 91 import java.util.concurrent.TimeUnit; 92 import java.util.function.BiConsumer; 93 94 @RunWith(AndroidJUnit4.class) 95 @Presubmit 96 public class ActivityManagerProcessStateTest { 97 private static final String TAG = ActivityManagerProcessStateTest.class.getName(); 98 99 private static final String STUB_PACKAGE_NAME = "android.app.stubs"; 100 private static final String PACKAGE_NAME_APP1 = "com.android.app1"; 101 private static final String PACKAGE_NAME_APP2 = "com.android.app2"; 102 private static final String PACKAGE_NAME_APP3 = "com.android.app3"; 103 104 private static final String[] PACKAGE_NAMES = { 105 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, PACKAGE_NAME_APP3 106 }; 107 108 private static final int WAIT_TIME = 10000; 109 private static final int WAITFOR_MSEC = 10000; 110 private static final int WAITFOR_ORDERED_BROADCAST_DRAINED = 60000; 111 // A secondary test activity from another APK. 112 static final String SIMPLE_PACKAGE_NAME = "com.android.cts.launcherapps.simpleapp"; 113 static final String SIMPLE_SERVICE = ".SimpleService"; 114 static final String SIMPLE_SERVICE2 = ".SimpleService2"; 115 static final String SIMPLE_SERVICE3 = ".SimpleService3"; 116 static final String SIMPLE_RECEIVER_START_SERVICE = ".SimpleReceiverStartService"; 117 static final String SIMPLE_ACTIVITY_START_SERVICE = ".SimpleActivityStartService"; 118 static final String SIMPLE_ACTIVITY_START_FG_SERVICE = ".SimpleActivityStartFgService"; 119 public static String ACTION_SIMPLE_ACTIVITY_START_SERVICE_RESULT = 120 "com.android.cts.launcherapps.simpleapp.SimpleActivityStartService.RESULT"; 121 static final String ACTION_SIMPLE_ACTIVITY_START_FG = 122 "com.android.cts.launcherapps.simpleapp.SimpleActivityStartFgService.START_THEN_FG"; 123 public static String ACTION_SIMPLE_ACTIVITY_START_FG_SERVICE_RESULT = 124 "com.android.cts.launcherapps.simpleapp.SimpleActivityStartFgService.NOW_FOREGROUND"; 125 public static String ACTION_FINISH_EVERYTHING = 126 "com.android.cts.launcherapps.simpleapp.SimpleActivityStartFgService.FINISH_ALL"; 127 128 // APKs for testing heavy weight app interactions. 129 static final String CANT_SAVE_STATE_1_PACKAGE_NAME = "com.android.test.cantsavestate1"; 130 static final String CANT_SAVE_STATE_2_PACKAGE_NAME = "com.android.test.cantsavestate2"; 131 132 // Actions 133 static final String ACTION_START_FOREGROUND = "com.android.test.action.START_FOREGROUND"; 134 static final String ACTION_STOP_FOREGROUND = "com.android.test.action.STOP_FOREGROUND"; 135 static final String ACTION_START_THEN_FG = "com.android.test.action.START_THEN_FG"; 136 static final String ACTION_STOP_SERVICE = "com.android.test.action.STOP"; 137 static final String ACTION_FINISH = "com.android.test.action.FINISH"; 138 139 private static final int TEMP_WHITELIST_DURATION_MS = 2000; 140 141 private Context mContext; 142 private Context mTargetContext; 143 private Instrumentation mInstrumentation; 144 private Intent mServiceIntent; 145 private Intent mServiceStartForegroundIntent; 146 private Intent mServiceStopForegroundIntent; 147 private Intent mService2Intent; 148 private Intent mService3Intent; 149 private Intent mServiceStartForeground3Intent; 150 private Intent mMainProcess[]; 151 private Intent mAllProcesses[]; 152 153 private int mAppCount; 154 private ApplicationInfo[] mAppInfo; 155 private WatchUidRunner[] mWatchers; 156 157 @Before setUp()158 public void setUp() throws Exception { 159 mInstrumentation = InstrumentationRegistry.getInstrumentation(); 160 mContext = mInstrumentation.getContext(); 161 mTargetContext = mInstrumentation.getTargetContext(); 162 mServiceIntent = new Intent(); 163 mServiceIntent.setClassName(SIMPLE_PACKAGE_NAME, SIMPLE_PACKAGE_NAME + SIMPLE_SERVICE); 164 mServiceStartForegroundIntent = new Intent(mServiceIntent); 165 mServiceStartForegroundIntent.setAction(ACTION_START_FOREGROUND); 166 mServiceStopForegroundIntent = new Intent(mServiceIntent); 167 mServiceStopForegroundIntent.setAction(ACTION_STOP_FOREGROUND); 168 mService2Intent = new Intent() 169 .setClassName(SIMPLE_PACKAGE_NAME, SIMPLE_PACKAGE_NAME + SIMPLE_SERVICE2); 170 mService3Intent = new Intent() 171 .setClassName(SIMPLE_PACKAGE_NAME, SIMPLE_PACKAGE_NAME + SIMPLE_SERVICE3); 172 mMainProcess = new Intent[1]; 173 mMainProcess[0] = mServiceIntent; 174 mAllProcesses = new Intent[2]; 175 mAllProcesses[0] = mServiceIntent; 176 mAllProcesses[1] = mService2Intent; 177 mContext.stopService(mServiceIntent); 178 mContext.stopService(mService2Intent); 179 mContext.stopService(mService3Intent); 180 CtsAppTestUtils.turnScreenOn(mInstrumentation, mContext); 181 removeTestAppFromWhitelists(); 182 mAppCount = 0; 183 drainOrderedBroadcastQueue(); 184 // Make sure we are in Home screen before starting the test 185 mInstrumentation.getUiAutomation().performGlobalAction( 186 AccessibilityService.GLOBAL_ACTION_HOME); 187 // Stop all the packages to avoid residual impact 188 final ActivityManager am = mContext.getSystemService(ActivityManager.class); 189 for (int i = 0; i < PACKAGE_NAMES.length; i++) { 190 final String pkgName = PACKAGE_NAMES[i]; 191 SystemUtil.runWithShellPermissionIdentity(() -> { 192 am.forceStopPackage(pkgName); 193 }); 194 } 195 } 196 197 @After tearDown()198 public void tearDown() throws Exception { 199 // Stop all the packages 200 final List<String> allPackageNames = new ArrayList<>(); 201 allPackageNames.addAll(Arrays.asList(PACKAGE_NAMES)); 202 allPackageNames.add(SIMPLE_PACKAGE_NAME); 203 allPackageNames.add(CANT_SAVE_STATE_1_PACKAGE_NAME); 204 allPackageNames.add(CANT_SAVE_STATE_2_PACKAGE_NAME); 205 final ActivityManager am = mContext.getSystemService(ActivityManager.class); 206 for (final String pkgName : allPackageNames) { 207 SystemUtil.runWithShellPermissionIdentity(() -> { 208 am.forceStopPackage(pkgName); 209 }); 210 } 211 } 212 213 /** 214 * Drain the ordered broadcast queue, it'll be useful when the test runs in secondary user 215 * which is just created prior to the testing, the ordered broadcast queue could be clogged. 216 */ drainOrderedBroadcastQueue()217 private void drainOrderedBroadcastQueue() throws Exception { 218 final CountDownLatch latch = new CountDownLatch(1); 219 final BroadcastReceiver receiver = new BroadcastReceiver() { 220 @Override 221 public void onReceive(Context context, Intent intent) { 222 latch.countDown(); 223 } 224 }; 225 CommandReceiver.sendCommandWithResultReceiver(mContext, CommandReceiver.COMMAND_EMPTY, 226 STUB_PACKAGE_NAME, STUB_PACKAGE_NAME, 0, null, receiver); 227 latch.await(WAITFOR_ORDERED_BROADCAST_DRAINED, TimeUnit.MILLISECONDS); 228 Log.i(TAG, "Ordered broadcast queue drained"); 229 } 230 231 /** 232 * Set up count app info objects and WatchUidRunners. 233 */ setupWatchers(int count)234 private void setupWatchers(int count) throws Exception { 235 mAppCount = count; 236 mAppInfo = new ApplicationInfo[count]; 237 mWatchers = new WatchUidRunner[count]; 238 for (int i = 0; i < count; i++) { 239 mAppInfo[i] = mContext.getPackageManager().getApplicationInfo( 240 PACKAGE_NAMES[i], 0); 241 mWatchers[i] = new WatchUidRunner(mInstrumentation, mAppInfo[i].uid, 242 WAITFOR_MSEC); 243 } 244 } 245 246 /** 247 * Finish all started WatchUidRunners. 248 */ shutdownWatchers()249 private void shutdownWatchers() throws Exception { 250 for (int i = 0; i < mAppCount; i++) { 251 mWatchers[i].finish(); 252 } 253 } 254 removeTestAppFromWhitelists()255 private void removeTestAppFromWhitelists() throws Exception { 256 CtsAppTestUtils.executeShellCmd(mInstrumentation, 257 "cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME); 258 CtsAppTestUtils.executeShellCmd(mInstrumentation, 259 "cmd deviceidle tempwhitelist -r " + SIMPLE_PACKAGE_NAME); 260 } 261 waitForAppFocus(String waitForApp, long waitTime)262 private void waitForAppFocus(String waitForApp, long waitTime) { 263 final WindowManagerStateHelper wms = new WindowManagerStateHelper(); 264 long waitUntil = SystemClock.elapsedRealtime() + waitTime; 265 while (true) { 266 wms.computeState(); 267 String appName = wms.getFocusedApp(); 268 if (appName != null) { 269 ComponentName comp = ComponentName.unflattenFromString(appName); 270 if (waitForApp.equals(comp.getPackageName())) { 271 break; 272 } 273 } 274 if (SystemClock.elapsedRealtime() > waitUntil) { 275 throw new IllegalStateException("Timed out waiting for focus on app " 276 + waitForApp + ", last was " + appName); 277 } 278 Log.i(TAG, "Waiting for app focus, current: " + appName); 279 try { 280 Thread.sleep(100); 281 } catch (InterruptedException e) { 282 } 283 } 284 } 285 startActivity(Context context, final Intent intent)286 private void startActivity(Context context, final Intent intent) { 287 ActivityOptions activityOptions = ActivityOptions.makeBasic(); 288 activityOptions.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN); 289 context.startActivity(intent, activityOptions.toBundle()); 290 } 291 startAndWaitForHeavyWeightSwitcherActivity(final Intent intent)292 private void startAndWaitForHeavyWeightSwitcherActivity(final Intent intent) { 293 startActivity(mTargetContext, intent); 294 // Assume there was another CANT_SAVE_STATE app, so it will redirect to the switch activity. 295 new WindowManagerStateHelper().waitAndAssertWindowSurfaceShown( 296 "android/com.android.internal.app.HeavyWeightSwitcherActivity", true); 297 // Wait for the transition animation to complete. 298 mInstrumentation.getUiAutomation().syncInputTransactions(); 299 } 300 maybeClick(UiDevice device, UiSelector sel)301 private void maybeClick(UiDevice device, UiSelector sel) { 302 try { 303 device.findObject(sel).click(); 304 } catch (Throwable ignored) { 305 } 306 } 307 maybeClick(UiDevice device, BySelector sel)308 private void maybeClick(UiDevice device, BySelector sel) { 309 try { 310 device.findObject(sel).click(); 311 } catch (Throwable ignored) { 312 } 313 } 314 315 /** 316 * Test basic state changes as processes go up and down due to services running in them. 317 */ 318 @Test testUidImportanceListener()319 public void testUidImportanceListener() throws Exception { 320 final Parcel data = Parcel.obtain(); 321 ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext, mServiceIntent, 322 WAIT_TIME); 323 ServiceConnectionHandler conn2 = new ServiceConnectionHandler(mContext, mService2Intent, 324 WAIT_TIME); 325 326 ActivityManager am = mContext.getSystemService(ActivityManager.class); 327 328 ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo( 329 SIMPLE_PACKAGE_NAME, 0); 330 UidImportanceListener uidForegroundListener = new UidImportanceListener(mContext, 331 appInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE, WAIT_TIME); 332 333 PermissionUtils.revokePermission( 334 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS); 335 boolean gotException = false; 336 try { 337 uidForegroundListener.register(); 338 } catch (SecurityException e) { 339 gotException = true; 340 } 341 assertTrue("Expected SecurityException thrown", gotException); 342 343 PermissionUtils.grantPermission( 344 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS); 345 /* 346 Log.d("XXXX", "Invoke: " + cmd); 347 Log.d("XXXX", "Result: " + result); 348 Log.d("XXXX", SystemUtil.runShellCommand(mInstrumentation, "dumpsys package " 349 + STUB_PACKAGE_NAME)); 350 */ 351 uidForegroundListener.register(); 352 353 UidImportanceListener uidGoneListener = new UidImportanceListener(mContext, 354 appInfo.uid, IMPORTANCE_CACHED, WAIT_TIME); 355 uidGoneListener.register(); 356 357 WatchUidRunner uidWatcher = new WatchUidRunner(mInstrumentation, appInfo.uid, 358 WAIT_TIME); 359 360 try { 361 // First kill the processes to start out in a stable state. 362 conn.bind(); 363 conn2.bind(); 364 IBinder service1 = conn.getServiceIBinder(); 365 IBinder service2 = conn2.getServiceIBinder(); 366 conn.unbind(); 367 conn2.unbind(); 368 try { 369 service1.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0); 370 } catch (RemoteException e) { 371 } 372 try { 373 service2.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0); 374 } catch (RemoteException e) { 375 } 376 service1 = service2 = null; 377 378 // Wait for uid's processes to go away. 379 uidGoneListener.waitForValue(IMPORTANCE_GONE, IMPORTANCE_GONE); 380 assertEquals(IMPORTANCE_GONE, am.getPackageImportance(SIMPLE_PACKAGE_NAME)); 381 382 // And wait for the uid report to be gone. 383 uidWatcher.waitFor(WatchUidRunner.CMD_GONE, null); 384 385 // Now bind and see if we get told about the uid coming in to the foreground. 386 conn.bind(); 387 uidForegroundListener.waitForValue(IMPORTANCE_FOREGROUND, IMPORTANCE_VISIBLE); 388 assertEquals(IMPORTANCE_FOREGROUND_SERVICE, 389 am.getPackageImportance(SIMPLE_PACKAGE_NAME)); 390 391 // Also make sure the uid state reports are as expected. Wait for active because 392 // there may be some intermediate states as the process comes up. 393 uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null); 394 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 395 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 396 397 // Pull out the service IBinder for a kludy hack... 398 IBinder service = conn.getServiceIBinder(); 399 400 // Now unbind and see if we get told about it going to the background. 401 conn.unbind(); 402 uidForegroundListener.waitForValue(IMPORTANCE_CACHED, IMPORTANCE_CACHED); 403 assertEquals(IMPORTANCE_CACHED, am.getPackageImportance(SIMPLE_PACKAGE_NAME)); 404 405 uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null); 406 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 407 408 // Now kill the process and see if we are told about it being gone. 409 try { 410 service.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0); 411 } catch (RemoteException e) { 412 // It is okay if it is already gone for some reason. 413 } 414 415 uidGoneListener.waitForValue(IMPORTANCE_GONE, IMPORTANCE_GONE); 416 assertEquals(IMPORTANCE_GONE, am.getPackageImportance(SIMPLE_PACKAGE_NAME)); 417 418 uidWatcher.expect(WatchUidRunner.CMD_IDLE, null); 419 uidWatcher.expect(WatchUidRunner.CMD_GONE, null); 420 421 // Now we are going to try different combinations of binding to two processes to 422 // see if they are correctly combined together for the app. 423 424 // Bring up both services. 425 conn.bind(); 426 conn2.bind(); 427 uidForegroundListener.waitForValue(IMPORTANCE_FOREGROUND, IMPORTANCE_VISIBLE); 428 assertEquals(IMPORTANCE_FOREGROUND_SERVICE, 429 am.getPackageImportance(SIMPLE_PACKAGE_NAME)); 430 431 // Also make sure the uid state reports are as expected. 432 uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null); 433 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 434 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 435 436 // Bring down one service, app state should remain foreground. 437 conn2.unbind(); 438 assertEquals(IMPORTANCE_FOREGROUND_SERVICE, 439 am.getPackageImportance(SIMPLE_PACKAGE_NAME)); 440 441 // Bring down other service, app state should now be cached. (If the processes both 442 // actually get killed immediately, this is also not a correctly behaving system.) 443 conn.unbind(); 444 uidGoneListener.waitForValue(IMPORTANCE_CACHED, IMPORTANCE_CACHED); 445 assertEquals(IMPORTANCE_CACHED, 446 am.getPackageImportance(SIMPLE_PACKAGE_NAME)); 447 448 uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null); 449 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 450 451 // Bring up one service, this should be sufficient to become foreground. 452 conn2.bind(); 453 uidForegroundListener.waitForValue(IMPORTANCE_FOREGROUND, IMPORTANCE_VISIBLE); 454 assertEquals(IMPORTANCE_FOREGROUND_SERVICE, 455 am.getPackageImportance(SIMPLE_PACKAGE_NAME)); 456 457 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 458 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 459 460 // Bring up other service, should remain foreground. 461 conn.bind(); 462 assertEquals(IMPORTANCE_FOREGROUND_SERVICE, 463 am.getPackageImportance(SIMPLE_PACKAGE_NAME)); 464 465 // Bring down one service, should remain foreground. 466 conn.unbind(); 467 assertEquals(IMPORTANCE_FOREGROUND_SERVICE, 468 am.getPackageImportance(SIMPLE_PACKAGE_NAME)); 469 470 // And bringing down other service should put us back to cached. 471 conn2.unbind(); 472 uidGoneListener.waitForValue(IMPORTANCE_CACHED, 473 IMPORTANCE_CACHED); 474 assertEquals(IMPORTANCE_CACHED, 475 am.getPackageImportance(SIMPLE_PACKAGE_NAME)); 476 477 uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null); 478 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 479 } finally { 480 data.recycle(); 481 uidWatcher.finish(); 482 uidForegroundListener.unregister(); 483 uidGoneListener.unregister(); 484 } 485 } 486 487 /** 488 * Test that background check correctly prevents idle services from running but allows 489 * whitelisted apps to bypass the check. 490 */ 491 @Test testBackgroundCheckService()492 public void testBackgroundCheckService() throws Exception { 493 final Parcel data = Parcel.obtain(); 494 Intent serviceIntent = new Intent(); 495 serviceIntent.setClassName(SIMPLE_PACKAGE_NAME, 496 SIMPLE_PACKAGE_NAME + SIMPLE_SERVICE); 497 ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext, serviceIntent, 498 WAIT_TIME); 499 500 ActivityManager am = mContext.getSystemService(ActivityManager.class); 501 502 PermissionUtils.grantPermission( 503 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS); 504 /* 505 Log.d("XXXX", "Invoke: " + cmd); 506 Log.d("XXXX", "Result: " + result); 507 Log.d("XXXX", SystemUtil.runShellCommand(mInstrumentation, "dumpsys package " 508 + STUB_PACKAGE_NAME)); 509 */ 510 511 ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo( 512 SIMPLE_PACKAGE_NAME, 0); 513 514 UidImportanceListener uidForegroundListener = new UidImportanceListener(mContext, 515 appInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE, WAIT_TIME); 516 uidForegroundListener.register(); 517 UidImportanceListener uidGoneListener = new UidImportanceListener(mContext, 518 appInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY, WAIT_TIME); 519 uidGoneListener.register(); 520 521 WatchUidRunner uidWatcher = new WatchUidRunner(mInstrumentation, appInfo.uid, 522 WAIT_TIME); 523 524 final int userId = UserHandle.getUserId(appInfo.uid); 525 526 // First kill the process to start out in a stable state. 527 mContext.stopService(serviceIntent); 528 conn.bind(); 529 IBinder service = conn.getServiceIBinder(); 530 conn.unbind(); 531 try { 532 service.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0); 533 } catch (RemoteException e) { 534 } 535 service = null; 536 537 // Wait for uid's process to go away. 538 uidGoneListener.waitForValue(IMPORTANCE_GONE, IMPORTANCE_GONE); 539 assertEquals(IMPORTANCE_GONE, 540 am.getPackageImportance(SIMPLE_PACKAGE_NAME)); 541 542 // And wait for the uid report to be gone. 543 uidWatcher.waitFor(WatchUidRunner.CMD_GONE, null); 544 545 String cmd = "appops set --user " + userId + " " 546 + SIMPLE_PACKAGE_NAME + " RUN_IN_BACKGROUND deny"; 547 String result = SystemUtil.runShellCommand(mInstrumentation, cmd); 548 549 // This is a side-effect of the app op command. 550 uidWatcher.expect(WatchUidRunner.CMD_IDLE, null); 551 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, "NONE"); 552 553 // We don't want to wait for the uid to actually go idle, we can force it now. 554 cmd = "am make-uid-idle --user " + userId + " " + SIMPLE_PACKAGE_NAME; 555 result = SystemUtil.runShellCommand(mInstrumentation, cmd); 556 557 // Make sure app is not yet on whitelist 558 cmd = "cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME; 559 result = SystemUtil.runShellCommand(mInstrumentation, cmd); 560 561 // We will use this to monitor when the service is running. 562 conn.startMonitoring(); 563 564 try { 565 // Try starting the service. Should fail! 566 boolean failed = false; 567 try { 568 mContext.startService(serviceIntent); 569 } catch (IllegalStateException e) { 570 failed = true; 571 } 572 if (!failed) { 573 fail("Service was allowed to start while in the background"); 574 } 575 576 // Put app on temporary whitelist to see if this allows the service start. 577 cmd = String.format("cmd deviceidle tempwhitelist -u %d -d %d %s", 578 userId, TEMP_WHITELIST_DURATION_MS, SIMPLE_PACKAGE_NAME); 579 result = SystemUtil.runShellCommand(mInstrumentation, cmd); 580 581 // Try starting the service now that the app is whitelisted... should work! 582 mContext.startService(serviceIntent); 583 conn.waitForConnect(); 584 585 // Also make sure the uid state reports are as expected. 586 uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null); 587 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 588 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE); 589 590 // Good, now stop the service and give enough time to get off the temp whitelist. 591 mContext.stopService(serviceIntent); 592 conn.waitForDisconnect(); 593 594 uidWatcher.expect(WatchUidRunner.CMD_CACHED, null); 595 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 596 597 CtsAppTestUtils.executeShellCmd(mInstrumentation, 598 "cmd deviceidle tempwhitelist -u " + userId + " -r " + SIMPLE_PACKAGE_NAME); 599 600 // Going off the temp whitelist causes a spurious proc state report... that's 601 // not ideal, but okay. 602 // uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 603 604 // We don't want to wait for the uid to actually go idle, we can force it now. 605 cmd = "am make-uid-idle --user " + userId + " " + SIMPLE_PACKAGE_NAME; 606 result = SystemUtil.runShellCommand(mInstrumentation, cmd); 607 608 uidWatcher.expect(WatchUidRunner.CMD_IDLE, null); 609 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 610 611 // Now that we should be off the temp whitelist, make sure we again can't start. 612 failed = false; 613 try { 614 mContext.startService(serviceIntent); 615 } catch (IllegalStateException e) { 616 failed = true; 617 } 618 if (!failed) { 619 fail("Service was allowed to start while in the background"); 620 } 621 622 // Now put app on whitelist, should allow service to run. 623 cmd = "cmd deviceidle whitelist +" + SIMPLE_PACKAGE_NAME; 624 result = SystemUtil.runShellCommand(mInstrumentation, cmd); 625 626 // Try starting the service now that the app is whitelisted... should work! 627 mContext.startService(serviceIntent); 628 conn.waitForConnect(); 629 630 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 631 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE); 632 633 // Okay, bring down the service. 634 mContext.stopService(serviceIntent); 635 conn.waitForDisconnect(); 636 637 uidWatcher.expect(WatchUidRunner.CMD_CACHED, null); 638 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 639 640 } finally { 641 mContext.stopService(serviceIntent); 642 conn.stopMonitoring(); 643 644 uidWatcher.finish(); 645 646 cmd = "appops set --user " + userId + " " 647 + SIMPLE_PACKAGE_NAME + " RUN_IN_BACKGROUND allow"; 648 result = SystemUtil.runShellCommand(mInstrumentation, cmd); 649 cmd = "cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME; 650 result = SystemUtil.runShellCommand(mInstrumentation, cmd); 651 652 uidGoneListener.unregister(); 653 uidForegroundListener.unregister(); 654 655 data.recycle(); 656 } 657 } 658 659 /** 660 * Test that background check behaves correctly after a process is no longer foreground: first 661 * allowing a service to be started, then stopped by the system when idle. 662 */ 663 @Test testBackgroundCheckStopsService()664 public void testBackgroundCheckStopsService() throws Exception { 665 final Parcel data = Parcel.obtain(); 666 ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext, mServiceIntent, 667 WAIT_TIME); 668 ServiceConnectionHandler conn2 = new ServiceConnectionHandler(mContext, mService2Intent, 669 WAIT_TIME); 670 671 ActivityManager am = mContext.getSystemService(ActivityManager.class); 672 673 PermissionUtils.grantPermission( 674 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS); 675 /* 676 Log.d("XXXX", "Invoke: " + cmd); 677 Log.d("XXXX", "Result: " + result); 678 Log.d("XXXX", SystemUtil.runShellCommand(mInstrumentation, "dumpsys package " 679 + STUB_PACKAGE_NAME)); 680 */ 681 682 ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo( 683 SIMPLE_PACKAGE_NAME, 0); 684 685 UidImportanceListener uidServiceListener = new UidImportanceListener(mContext, 686 appInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE, WAIT_TIME); 687 uidServiceListener.register(); 688 UidImportanceListener uidGoneListener = new UidImportanceListener(mContext, 689 appInfo.uid, IMPORTANCE_CACHED, WAIT_TIME); 690 uidGoneListener.register(); 691 692 WatchUidRunner uidWatcher = new WatchUidRunner(mInstrumentation, appInfo.uid, 693 WAIT_TIME); 694 695 // First kill the process to start out in a stable state. 696 mContext.stopService(mServiceIntent); 697 mContext.stopService(mService2Intent); 698 conn.bind(); 699 conn2.bind(); 700 IBinder service = conn.getServiceIBinder(); 701 IBinder service2 = conn2.getServiceIBinder(); 702 conn.unbind(); 703 conn2.unbind(); 704 try { 705 service.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0); 706 } catch (RemoteException e) { 707 } 708 try { 709 service2.transact(IBinder.FIRST_CALL_TRANSACTION, data, null, 0); 710 } catch (RemoteException e) { 711 } 712 service = service2 = null; 713 714 // Wait for uid's process to go away. 715 uidGoneListener.waitForValue(IMPORTANCE_GONE, 716 IMPORTANCE_GONE); 717 assertEquals(IMPORTANCE_GONE, 718 am.getPackageImportance(SIMPLE_PACKAGE_NAME)); 719 720 // And wait for the uid report to be gone. 721 uidWatcher.waitFor(WatchUidRunner.CMD_GONE, null, WAIT_TIME); 722 723 String cmd = "appops set " + SIMPLE_PACKAGE_NAME + " RUN_IN_BACKGROUND deny"; 724 String result = SystemUtil.runShellCommand(mInstrumentation, cmd); 725 726 // This is a side-effect of the app op command. 727 uidWatcher.expect(WatchUidRunner.CMD_IDLE, null); 728 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_NONEXISTENT); 729 730 // We don't want to wait for the uid to actually go idle, we can force it now. 731 cmd = "am make-uid-idle " + SIMPLE_PACKAGE_NAME; 732 result = SystemUtil.runShellCommand(mInstrumentation, cmd); 733 734 // Make sure app is not yet on whitelist 735 cmd = "cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME; 736 result = SystemUtil.runShellCommand(mInstrumentation, cmd); 737 738 // We will use this to monitor when the service is running. 739 conn.startMonitoring(); 740 741 try { 742 // Try starting the service. Should fail! 743 boolean failed = false; 744 try { 745 mContext.startService(mServiceIntent); 746 } catch (IllegalStateException e) { 747 failed = true; 748 } 749 if (!failed) { 750 fail("Service was allowed to start while in the background"); 751 } 752 753 // First poke the process into the foreground, so we can avoid background check. 754 conn2.bind(); 755 conn2.waitForConnect(); 756 757 // Wait for process state to reflect running service. 758 uidServiceListener.waitForValue( 759 IMPORTANCE_FOREGROUND_SERVICE, 760 ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE); 761 assertEquals(IMPORTANCE_FOREGROUND_SERVICE, 762 am.getPackageImportance(SIMPLE_PACKAGE_NAME)); 763 764 // Also make sure the uid state reports are as expected. 765 uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null); 766 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 767 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 768 769 conn2.unbind(); 770 771 // Wait for process to recover back down to being cached. 772 uidServiceListener.waitForValue(IMPORTANCE_CACHED, 773 IMPORTANCE_GONE); 774 assertEquals(IMPORTANCE_CACHED, 775 am.getPackageImportance(SIMPLE_PACKAGE_NAME)); 776 777 uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null); 778 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 779 780 // Try starting the service now that the app is waiting to idle... should work! 781 mContext.startService(mServiceIntent); 782 conn.waitForConnect(); 783 784 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 785 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE); 786 787 // And also start the second service. 788 conn2.startMonitoring(); 789 mContext.startService(mService2Intent); 790 conn2.waitForConnect(); 791 792 // Force app to go idle now 793 cmd = "am make-uid-idle " + SIMPLE_PACKAGE_NAME; 794 result = SystemUtil.runShellCommand(mInstrumentation, cmd); 795 796 // Wait for services to be stopped by system. 797 uidServiceListener.waitForValue(IMPORTANCE_CACHED, 798 IMPORTANCE_GONE); 799 assertEquals(IMPORTANCE_CACHED, 800 am.getPackageImportance(SIMPLE_PACKAGE_NAME)); 801 802 // And service should be stopped by system, so just make sure it is disconnected. 803 conn.waitForDisconnect(); 804 conn2.waitForDisconnect(); 805 806 uidWatcher.expect(WatchUidRunner.CMD_IDLE, null); 807 // There may be a transient 'SVC' proc state here. 808 uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null); 809 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 810 811 } finally { 812 mContext.stopService(mServiceIntent); 813 mContext.stopService(mService2Intent); 814 conn.cleanup(); 815 conn2.cleanup(); 816 817 uidWatcher.finish(); 818 819 cmd = "appops set " + SIMPLE_PACKAGE_NAME + " RUN_IN_BACKGROUND allow"; 820 result = SystemUtil.runShellCommand(mInstrumentation, cmd); 821 cmd = "cmd deviceidle whitelist -" + SIMPLE_PACKAGE_NAME; 822 result = SystemUtil.runShellCommand(mInstrumentation, cmd); 823 824 uidGoneListener.unregister(); 825 uidServiceListener.unregister(); 826 827 data.recycle(); 828 } 829 } 830 831 /** 832 * Test the background check doesn't allow services to be started from broadcasts except when in 833 * the correct states. 834 */ 835 @Test testBackgroundCheckBroadcastService()836 public void testBackgroundCheckBroadcastService() throws Exception { 837 final Intent broadcastIntent = new Intent(); 838 broadcastIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND); 839 broadcastIntent.setClassName(SIMPLE_PACKAGE_NAME, 840 SIMPLE_PACKAGE_NAME + SIMPLE_RECEIVER_START_SERVICE); 841 842 PermissionUtils.grantPermission( 843 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS); 844 final ServiceProcessController controller = new ServiceProcessController(mContext, 845 mInstrumentation, STUB_PACKAGE_NAME, mAllProcesses, WAIT_TIME); 846 final ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext, 847 mServiceIntent, WAIT_TIME); 848 final WatchUidRunner uidWatcher = controller.getUidWatcher(); 849 850 try { 851 // First kill the process to start out in a stable state. 852 controller.ensureProcessGone(); 853 854 // Do initial setup. 855 controller.denyBackgroundOp(); 856 controller.makeUidIdle(); 857 controller.removeFromWhitelist(); 858 859 // We will use this to monitor when the service is running. 860 conn.startMonitoring(); 861 862 // Try sending broadcast to start the service. Should fail! 863 SyncOrderedBroadcast br = new SyncOrderedBroadcast(); 864 broadcastIntent.putExtra("service", mServiceIntent); 865 br.sendAndWait(mContext, broadcastIntent, Activity.RESULT_OK, null, null, WAIT_TIME); 866 int brCode = br.getReceivedCode(); 867 if (brCode != Activity.RESULT_CANCELED) { 868 fail("Didn't fail starting service, result=" + brCode); 869 } 870 871 // Track the uid proc state changes from the broadcast (but not service execution) 872 uidWatcher.waitFor(WatchUidRunner.CMD_IDLE, null, WAIT_TIME); 873 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null, WAIT_TIME); 874 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_RECEIVER, 875 WAIT_TIME); 876 uidWatcher.expect(WatchUidRunner.CMD_CACHED, null, WAIT_TIME); 877 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY, 878 WAIT_TIME); 879 880 // Put app on temporary whitelist to see if this allows the service start. 881 controller.tempWhitelist(TEMP_WHITELIST_DURATION_MS); 882 883 // Being on the whitelist means the uid is now active. 884 uidWatcher.expect(WatchUidRunner.CMD_ACTIVE, null, WAIT_TIME); 885 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY, 886 WAIT_TIME); 887 888 // Try starting the service now that the app is whitelisted... should work! 889 br.sendAndWait(mContext, broadcastIntent, Activity.RESULT_OK, null, null, WAIT_TIME); 890 brCode = br.getReceivedCode(); 891 if (brCode != Activity.RESULT_FIRST_USER) { 892 fail("Failed starting service, result=" + brCode); 893 } 894 conn.waitForConnect(); 895 896 // Also make sure the uid state reports are as expected. 897 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 898 // We are going to wait until 'SVC', because we may see an intermediate 'RCVR' 899 // proc state depending on timing. 900 uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE); 901 902 // Good, now stop the service and give enough time to get off the temp whitelist. 903 mContext.stopService(mServiceIntent); 904 conn.waitForDisconnect(); 905 906 uidWatcher.expect(WatchUidRunner.CMD_CACHED, null); 907 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 908 909 controller.removeFromTempWhitelist(); 910 911 // Going off the temp whitelist causes a spurious proc state report... that's 912 // not ideal, but okay. 913 // uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 914 915 // We don't want to wait for the uid to actually go idle, we can force it now. 916 controller.makeUidIdle(); 917 918 uidWatcher.expect(WatchUidRunner.CMD_IDLE, null); 919 920 // Make sure the process is gone so we start over fresh. 921 controller.ensureProcessGone(); 922 923 // Now that we should be off the temp whitelist, make sure we again can't start. 924 br.sendAndWait(mContext, broadcastIntent, Activity.RESULT_OK, null, null, WAIT_TIME); 925 brCode = br.getReceivedCode(); 926 if (brCode != Activity.RESULT_CANCELED) { 927 fail("Didn't fail starting service, result=" + brCode); 928 } 929 930 // Track the uid proc state changes from the broadcast (but not service execution) 931 uidWatcher.waitFor(WatchUidRunner.CMD_IDLE, null); 932 // There could be a transient 'cached' state here before 'uncached' if uid state 933 // changes are dispatched before receiver is started. 934 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 935 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_RECEIVER); 936 uidWatcher.expect(WatchUidRunner.CMD_CACHED, null); 937 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 938 939 // Now put app on whitelist, should allow service to run. 940 controller.addToWhitelist(); 941 942 // Try starting the service now that the app is whitelisted... should work! 943 br.sendAndWait(mContext, broadcastIntent, Activity.RESULT_OK, null, null, WAIT_TIME); 944 brCode = br.getReceivedCode(); 945 if (brCode != Activity.RESULT_FIRST_USER) { 946 fail("Failed starting service, result=" + brCode); 947 } 948 conn.waitForConnect(); 949 950 // Also make sure the uid state reports are as expected. 951 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 952 uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE); 953 954 // Okay, bring down the service. 955 mContext.stopService(mServiceIntent); 956 conn.waitForDisconnect(); 957 958 uidWatcher.expect(WatchUidRunner.CMD_CACHED, null); 959 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 960 961 } finally { 962 mContext.stopService(mServiceIntent); 963 conn.stopMonitoringIfNeeded(); 964 controller.cleanup(); 965 } 966 } 967 968 /** 969 * Test that background check does allow services to be started from activities. 970 */ 971 @Test testBackgroundCheckActivityService()972 public void testBackgroundCheckActivityService() throws Exception { 973 final Intent activityIntent = new Intent(); 974 activityIntent.setClassName(SIMPLE_PACKAGE_NAME, 975 SIMPLE_PACKAGE_NAME + SIMPLE_ACTIVITY_START_SERVICE); 976 activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 977 978 PermissionUtils.grantPermission( 979 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS); 980 final ServiceProcessController controller = new ServiceProcessController(mContext, 981 mInstrumentation, STUB_PACKAGE_NAME, mAllProcesses, WAIT_TIME); 982 final ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext, 983 mServiceIntent, WAIT_TIME); 984 final WatchUidRunner uidWatcher = controller.getUidWatcher(); 985 986 try { 987 // First kill the process to start out in a stable state. 988 controller.ensureProcessGone(); 989 990 // Do initial setup. 991 controller.denyBackgroundOp(); 992 controller.makeUidIdle(); 993 controller.removeFromWhitelist(); 994 995 // We will use this to monitor when the service is running. 996 conn.startMonitoring(); 997 998 // Try starting activity that will start the service. This should be okay. 999 WaitForBroadcast waiter = new WaitForBroadcast(mInstrumentation.getTargetContext()); 1000 waiter.prepare(ACTION_SIMPLE_ACTIVITY_START_SERVICE_RESULT); 1001 activityIntent.putExtra("service", mServiceIntent); 1002 startActivity(mTargetContext, activityIntent); 1003 Intent resultIntent = waiter.doWait(WAIT_TIME * 2); 1004 int brCode = resultIntent.getIntExtra("result", Activity.RESULT_CANCELED); 1005 if (brCode != Activity.RESULT_FIRST_USER) { 1006 fail("Failed starting service, result=" + brCode); 1007 } 1008 conn.waitForConnect(); 1009 1010 final String expectedActivityState = (CtsAppTestUtils.isScreenInteractive(mContext) 1011 && !CtsAppTestUtils.isKeyguardLocked(mContext)) 1012 ? WatchUidRunner.STATE_TOP : WatchUidRunner.STATE_TOP_SLEEPING; 1013 // Also make sure the uid state reports are as expected. 1014 uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null); 1015 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 1016 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, expectedActivityState); 1017 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE); 1018 1019 // Okay, bring down the service. 1020 mContext.stopService(mServiceIntent); 1021 conn.waitForDisconnect(); 1022 1023 uidWatcher.expect(WatchUidRunner.CMD_CACHED, null); 1024 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1025 1026 // App isn't yet idle, so we should be able to start the service again. 1027 mContext.startService(mServiceIntent); 1028 conn.waitForConnect(); 1029 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 1030 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE); 1031 1032 // And now fast-forward to the app going idle, service should be stopped. 1033 controller.makeUidIdle(); 1034 uidWatcher.waitFor(WatchUidRunner.CMD_IDLE, null); 1035 1036 conn.waitForDisconnect(); 1037 uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null); 1038 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1039 1040 // No longer should be able to start service. 1041 boolean failed = false; 1042 try { 1043 mContext.startService(mServiceIntent); 1044 } catch (IllegalStateException e) { 1045 failed = true; 1046 } 1047 if (!failed) { 1048 fail("Service was allowed to start while in the background"); 1049 } 1050 1051 } finally { 1052 mContext.stopService(mServiceIntent); 1053 conn.stopMonitoringIfNeeded(); 1054 controller.cleanup(); 1055 } 1056 } 1057 1058 /** 1059 * Test that the foreground service app op does prevent the foreground state. 1060 */ 1061 @Test testForegroundServiceAppOp()1062 public void testForegroundServiceAppOp() throws Exception { 1063 PermissionUtils.grantPermission( 1064 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS); 1065 // Use default timeout value 5000 1066 final ServiceProcessController controller = new ServiceProcessController(mContext, 1067 mInstrumentation, STUB_PACKAGE_NAME, mAllProcesses); 1068 // Use default timeout value 5000 1069 final ServiceConnectionHandler conn = new ServiceConnectionHandler(mContext, 1070 mServiceIntent); 1071 final WatchUidRunner uidWatcher = controller.getUidWatcher(); 1072 1073 try { 1074 // First kill the process to start out in a stable state. 1075 controller.ensureProcessGone(); 1076 1077 // Do initial setup. 1078 controller.makeUidIdle(); 1079 controller.removeFromWhitelist(); 1080 controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "allow"); 1081 1082 // Put app on whitelist, to allow service to run. 1083 controller.addToWhitelist(); 1084 1085 // We will use this to monitor when the service is running. 1086 conn.startMonitoring(); 1087 1088 // -------- START SERVICE AND THEN SUCCESSFULLY GO TO FOREGROUND 1089 1090 // Now start the service and wait for it to come up. 1091 mContext.startService(mServiceStartForegroundIntent); 1092 conn.waitForConnect(); 1093 1094 // Also make sure the uid state reports are as expected. 1095 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 1096 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE); 1097 uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null); 1098 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1099 1100 // Now take it out of foreground and confirm. 1101 mContext.startService(mServiceStopForegroundIntent); 1102 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE); 1103 1104 // Good, now stop the service and wait for it to go away. 1105 mContext.stopService(mServiceStartForegroundIntent); 1106 conn.waitForDisconnect(); 1107 1108 // There may be a transient STATE_SERVICE we don't care about, so waitFor. 1109 uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null); 1110 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1111 1112 // We don't want to wait for the uid to actually go idle, we can force it now. 1113 controller.makeUidIdle(); 1114 uidWatcher.expect(WatchUidRunner.CMD_IDLE, null); 1115 1116 // Make sure the process is gone so we start over fresh. 1117 controller.ensureProcessGone(); 1118 1119 // -------- START SERVICE AND BLOCK GOING TO FOREGROUND 1120 1121 // Now we will deny the app op and ensure the service can't become foreground. 1122 controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "ignore"); 1123 1124 // Now start the service and wait for it to come up. 1125 mContext.startService(mServiceStartForegroundIntent); 1126 conn.waitForConnect(); 1127 1128 // Also make sure the uid state reports are as expected. 1129 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 1130 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE); 1131 1132 // Good, now stop the service and wait for it to go away. 1133 mContext.stopService(mServiceStartForegroundIntent); 1134 conn.waitForDisconnect(); 1135 1136 // THIS MUST BE AN EXPECT: we want to make sure we don't get in to STATE_FG_SERVICE. 1137 uidWatcher.expect(WatchUidRunner.CMD_CACHED, null); 1138 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1139 1140 // Make sure the uid is idle (it should be anyway, it never went active here). 1141 controller.makeUidIdle(); 1142 1143 // Make sure the process is gone so we start over fresh. 1144 controller.ensureProcessGone(); 1145 1146 // -------- DIRECT START FOREGROUND SERVICE SUCCESSFULLY 1147 1148 controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "allow"); 1149 1150 // Now start the service and wait for it to come up. 1151 mContext.startForegroundService(mServiceStartForegroundIntent); 1152 conn.waitForConnect(); 1153 1154 // Make sure it becomes a foreground service. The process state changes here 1155 // are weird looking because we first need to force the app out of idle to allow 1156 // it to start the service. 1157 uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null); 1158 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 1159 uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1160 // Remove tempwhitelist avoid temp white list block idle command and app crash occur. 1161 CtsAppTestUtils.executeShellCmd(mInstrumentation, 1162 "cmd deviceidle tempwhitelist -r " + SIMPLE_PACKAGE_NAME); 1163 // Good, now stop the service and wait for it to go away. 1164 mContext.stopService(mServiceStartForegroundIntent); 1165 conn.waitForDisconnect(); 1166 1167 // There may be a transient STATE_SERVICE we don't care about, so waitFor. 1168 uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null); 1169 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1170 1171 // We don't want to wait for the uid to actually go idle, we can force it now. 1172 controller.makeUidIdle(); 1173 1174 // Make sure the process is gone so we start over fresh. 1175 controller.ensureProcessGone(); 1176 1177 // -------- DIRECT START FOREGROUND SERVICE BLOCKED 1178 1179 // Now we will deny the app op and ensure the service can't become foreground. 1180 controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "ignore"); 1181 1182 // But we will put it on the whitelist so the service is still allowed to start. 1183 controller.addToWhitelist(); 1184 1185 // Now start the service and wait for it to come up. 1186 mContext.startForegroundService(mServiceStartForegroundIntent); 1187 conn.waitForConnect(); 1188 1189 // In this case we only get to run it as a regular service. 1190 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 1191 uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE); 1192 1193 // Good, now stop the service and wait for it to go away. 1194 mContext.stopService(mServiceStartForegroundIntent); 1195 conn.waitForDisconnect(); 1196 1197 // THIS MUST BE AN EXPECT: we want to make sure we don't get in to STATE_FG_SERVICE. 1198 uidWatcher.expect(WatchUidRunner.CMD_CACHED, null); 1199 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1200 1201 // Make sure the uid is idle (it should be anyway, it never went active here). 1202 controller.makeUidIdle(); 1203 1204 // Make sure the process is gone so we start over fresh. 1205 controller.ensureProcessGone(); 1206 1207 // -------- XXX NEED TO TEST NON-WHITELIST CASE WHERE NOTHING HAPPENS 1208 1209 } finally { 1210 mContext.stopService(mServiceStartForegroundIntent); 1211 conn.stopMonitoringIfNeeded(); 1212 controller.cleanup(); 1213 controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "allow"); 1214 controller.removeFromWhitelist(); 1215 } 1216 } 1217 1218 /** 1219 * Verify that an app under background restrictions has its foreground services demoted to 1220 * ordinary service state when it is no longer the top app. 1221 */ 1222 @Test testBgRestrictedForegroundService()1223 public void testBgRestrictedForegroundService() throws Exception { 1224 final Intent activityIntent = new Intent() 1225 .setClassName(SIMPLE_PACKAGE_NAME, 1226 SIMPLE_PACKAGE_NAME + SIMPLE_ACTIVITY_START_FG_SERVICE) 1227 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1228 1229 PermissionUtils.grantPermission( 1230 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS); 1231 final ServiceProcessController controller = new ServiceProcessController(mContext, 1232 mInstrumentation, STUB_PACKAGE_NAME, mAllProcesses, WAIT_TIME); 1233 final WatchUidRunner uidWatcher = controller.getUidWatcher(); 1234 1235 final Intent homeIntent = new Intent() 1236 .setAction(Intent.ACTION_MAIN) 1237 .addCategory(Intent.CATEGORY_HOME) 1238 .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK 1239 | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 1240 1241 final Intent serviceStartIntent = new Intent(mService3Intent) 1242 .setAction(ACTION_START_THEN_FG); 1243 activityIntent.putExtra("service", serviceStartIntent); 1244 boolean activityStarted = false; 1245 1246 try { 1247 // First kill the process to start out in a stable state. 1248 controller.ensureProcessGone(); 1249 1250 // Do initial setup. 1251 controller.denyAnyInBackgroundOp(); 1252 controller.makeUidIdle(); 1253 controller.removeFromWhitelist(); 1254 controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "allow"); 1255 1256 // Start the activity, which will start the fg service as well, and wait 1257 // for the report that it's all up and running. 1258 WaitForBroadcast waiter = new WaitForBroadcast(mInstrumentation.getTargetContext()); 1259 waiter.prepare(ACTION_SIMPLE_ACTIVITY_START_FG_SERVICE_RESULT); 1260 1261 activityIntent.setAction(ACTION_SIMPLE_ACTIVITY_START_FG); 1262 startActivity(mTargetContext, activityIntent); 1263 activityStarted = true; 1264 1265 Intent resultIntent = waiter.doWait(WAIT_TIME); 1266 int brCode = resultIntent.getIntExtra("result", Activity.RESULT_CANCELED); 1267 if (brCode != Activity.RESULT_FIRST_USER) { 1268 fail("Failed starting service, result=" + brCode); 1269 } 1270 1271 // activity is in front, fg service is running. make sure that we see 1272 // the expected state at this point. 1273 uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null); 1274 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 1275 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP); 1276 1277 // Switch to the home app; make sure the test app drops all the way 1278 // down to SERVICE, not FG_SERVICE 1279 mTargetContext.startActivity(homeIntent); 1280 uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE); 1281 } finally { 1282 // tear down everything and we're done 1283 if (activityStarted) { 1284 activityIntent.setAction(ACTION_FINISH_EVERYTHING); 1285 mTargetContext.startActivity(activityIntent); 1286 } 1287 1288 controller.cleanup(); 1289 } 1290 1291 } 1292 supportsCantSaveState()1293 private boolean supportsCantSaveState() { 1294 if (mContext.getPackageManager().hasSystemFeature( 1295 PackageManager.FEATURE_CANT_SAVE_STATE)) { 1296 return true; 1297 } 1298 1299 return false; 1300 } 1301 1302 /** 1303 * Test that a single "can't save state" app has the proper process management semantics. 1304 */ 1305 @Test testCantSaveStateLaunchAndBackground()1306 public void testCantSaveStateLaunchAndBackground() throws Exception { 1307 if (!supportsCantSaveState()) { 1308 return; 1309 } 1310 1311 final Intent activityIntent = new Intent(); 1312 activityIntent.setPackage(CANT_SAVE_STATE_1_PACKAGE_NAME); 1313 activityIntent.setAction(Intent.ACTION_MAIN); 1314 activityIntent.addCategory(Intent.CATEGORY_LAUNCHER); 1315 activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1316 1317 final Intent homeIntent = new Intent(); 1318 homeIntent.setAction(Intent.ACTION_MAIN); 1319 homeIntent.addCategory(Intent.CATEGORY_HOME); 1320 homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1321 1322 ActivityManager am = mContext.getSystemService(ActivityManager.class); 1323 1324 PermissionUtils.grantPermission( 1325 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS); 1326 1327 // We don't want to wait for the uid to actually go idle, we can force it now. 1328 String cmd = "am make-uid-idle " + CANT_SAVE_STATE_1_PACKAGE_NAME; 1329 String result = SystemUtil.runShellCommand(mInstrumentation, cmd); 1330 1331 ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo( 1332 CANT_SAVE_STATE_1_PACKAGE_NAME, 0); 1333 1334 // This test is also using UidImportanceListener to make sure the correct 1335 // heavy-weight state is reported there. 1336 UidImportanceListener uidForegroundListener = new UidImportanceListener(mContext, 1337 appInfo.uid, IMPORTANCE_FOREGROUND, 1338 WAIT_TIME); 1339 uidForegroundListener.register(); 1340 UidImportanceListener uidBackgroundListener = new UidImportanceListener(mContext, 1341 appInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE - 1, 1342 WAIT_TIME); 1343 uidBackgroundListener.register(); 1344 UidImportanceListener uidCachedListener = new UidImportanceListener(mContext, 1345 appInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE + 1, 1346 WAIT_TIME); 1347 uidCachedListener.register(); 1348 1349 WatchUidRunner uidWatcher = new WatchUidRunner(mInstrumentation, appInfo.uid, 1350 WAIT_TIME); 1351 1352 UiDevice device = UiDevice.getInstance(mInstrumentation); 1353 1354 try { 1355 // Start the heavy-weight app, should launch like a normal app. 1356 startActivity(mTargetContext, activityIntent); 1357 waitForAppFocus(CANT_SAVE_STATE_1_PACKAGE_NAME, WAIT_TIME); 1358 device.waitForIdle(); 1359 1360 // Wait for process state to reflect running activity. 1361 uidForegroundListener.waitForValue( 1362 IMPORTANCE_FOREGROUND, 1363 IMPORTANCE_FOREGROUND); 1364 assertEquals(IMPORTANCE_FOREGROUND, 1365 am.getPackageImportance(CANT_SAVE_STATE_1_PACKAGE_NAME)); 1366 1367 // Also make sure the uid state reports are as expected. 1368 uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null); 1369 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 1370 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP); 1371 1372 // Now go to home, leaving the app. It should be put in the heavy weight state. 1373 mTargetContext.startActivity(homeIntent); 1374 1375 final int expectedImportance = 1376 (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.O) 1377 ? ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE 1378 : ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE_PRE_26; 1379 // Wait for process to go down to background heavy-weight. 1380 uidBackgroundListener.waitForValue(expectedImportance, expectedImportance); 1381 assertEquals(expectedImportance, 1382 am.getPackageImportance(CANT_SAVE_STATE_1_PACKAGE_NAME)); 1383 1384 uidWatcher.expect(WatchUidRunner.CMD_CACHED, null); 1385 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_HEAVY_WEIGHT); 1386 1387 // While in background, should go in to normal idle state. 1388 // Force app to go idle now 1389 cmd = "am make-uid-idle " + CANT_SAVE_STATE_1_PACKAGE_NAME; 1390 result = SystemUtil.runShellCommand(mInstrumentation, cmd); 1391 uidWatcher.expect(WatchUidRunner.CMD_IDLE, null); 1392 1393 // Switch back to heavy-weight app to see if it correctly returns to foreground. 1394 startActivity(mTargetContext, activityIntent); 1395 1396 // Wait for process state to reflect running activity. 1397 uidForegroundListener.waitForValue( 1398 IMPORTANCE_FOREGROUND, 1399 IMPORTANCE_FOREGROUND); 1400 assertEquals(IMPORTANCE_FOREGROUND, 1401 am.getPackageImportance(CANT_SAVE_STATE_1_PACKAGE_NAME)); 1402 1403 // Also make sure the uid state reports are as expected. 1404 uidWatcher.waitFor(WatchUidRunner.CMD_ACTIVE, null); 1405 uidWatcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 1406 uidWatcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP); 1407 1408 waitForAppFocus(CANT_SAVE_STATE_1_PACKAGE_NAME, WAIT_TIME); 1409 device.waitForIdle(); 1410 1411 // Exit activity, check to see if we are now cached. 1412 final Intent finishIntent = new Intent(); 1413 finishIntent.setPackage(CANT_SAVE_STATE_1_PACKAGE_NAME); 1414 finishIntent.setAction(ACTION_FINISH); 1415 finishIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1416 finishIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 1417 mTargetContext.startActivity(finishIntent); 1418 1419 // Wait for process to become cached 1420 uidCachedListener.waitForValue( 1421 IMPORTANCE_CACHED, 1422 IMPORTANCE_CACHED); 1423 assertEquals(IMPORTANCE_CACHED, 1424 am.getPackageImportance(CANT_SAVE_STATE_1_PACKAGE_NAME)); 1425 1426 uidWatcher.expect(WatchUidRunner.CMD_CACHED, null); 1427 uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_RECENT); 1428 1429 // While in background, should go in to normal idle state. 1430 // Force app to go idle now 1431 cmd = "am make-uid-idle " + CANT_SAVE_STATE_1_PACKAGE_NAME; 1432 result = SystemUtil.runShellCommand(mInstrumentation, cmd); 1433 uidWatcher.expect(WatchUidRunner.CMD_IDLE, null); 1434 1435 } finally { 1436 uidWatcher.finish(); 1437 uidForegroundListener.unregister(); 1438 uidBackgroundListener.unregister(); 1439 uidCachedListener.unregister(); 1440 } 1441 } 1442 1443 /** 1444 * Test that switching between two "can't save state" apps is handled properly. 1445 */ 1446 @Test testCantSaveStateLaunchAndSwitch()1447 public void testCantSaveStateLaunchAndSwitch() throws Exception { 1448 if (!supportsCantSaveState()) { 1449 return; 1450 } 1451 1452 final Intent activity1Intent = new Intent(); 1453 activity1Intent.setPackage(CANT_SAVE_STATE_1_PACKAGE_NAME); 1454 activity1Intent.setAction(Intent.ACTION_MAIN); 1455 activity1Intent.addCategory(Intent.CATEGORY_LAUNCHER); 1456 activity1Intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1457 1458 final Intent activity2Intent = new Intent(); 1459 activity2Intent.setPackage(CANT_SAVE_STATE_2_PACKAGE_NAME); 1460 activity2Intent.setAction(Intent.ACTION_MAIN); 1461 activity2Intent.addCategory(Intent.CATEGORY_LAUNCHER); 1462 activity2Intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1463 1464 final Intent homeIntent = new Intent(); 1465 homeIntent.setAction(Intent.ACTION_MAIN); 1466 homeIntent.addCategory(Intent.CATEGORY_HOME); 1467 homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1468 1469 UiDevice device = UiDevice.getInstance(mInstrumentation); 1470 1471 PermissionUtils.grantPermission( 1472 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS); 1473 1474 // We don't want to wait for the uid to actually go idle, we can force it now. 1475 String cmd = "am make-uid-idle " + CANT_SAVE_STATE_1_PACKAGE_NAME; 1476 String result = SystemUtil.runShellCommand(mInstrumentation, cmd); 1477 cmd = "am make-uid-idle " + CANT_SAVE_STATE_2_PACKAGE_NAME; 1478 result = SystemUtil.runShellCommand(mInstrumentation, cmd); 1479 1480 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 1481 CANT_SAVE_STATE_1_PACKAGE_NAME, 0); 1482 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 1483 WAIT_TIME); 1484 1485 ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo( 1486 CANT_SAVE_STATE_2_PACKAGE_NAME, 0); 1487 WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid, 1488 WAIT_TIME); 1489 1490 try { 1491 // Start the first heavy-weight app, should launch like a normal app. 1492 startActivity(mTargetContext, activity1Intent); 1493 waitForAppFocus(CANT_SAVE_STATE_1_PACKAGE_NAME, WAIT_TIME); 1494 device.waitForIdle(); 1495 1496 // Make sure the uid state reports are as expected. 1497 uid1Watcher.waitFor(WatchUidRunner.CMD_ACTIVE, null); 1498 uid1Watcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 1499 uid1Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP); 1500 1501 // Now go to home, leaving the app. It should be put in the heavy weight state. 1502 mTargetContext.startActivity(homeIntent); 1503 1504 // Wait for process to go down to background heavy-weight. 1505 uid1Watcher.expect(WatchUidRunner.CMD_CACHED, null); 1506 uid1Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_HEAVY_WEIGHT); 1507 1508 // Start the second heavy-weight app, should ask us what to do with the two apps 1509 startAndWaitForHeavyWeightSwitcherActivity(activity2Intent); 1510 1511 // First, let's try returning to the original app. 1512 maybeClick(device, new UiSelector().resourceId("android:id/switch_old")); 1513 waitForAppFocus(CANT_SAVE_STATE_1_PACKAGE_NAME, WAIT_TIME); 1514 device.waitForIdle(); 1515 1516 // App should now be back in foreground. 1517 uid1Watcher.expect(WatchUidRunner.CMD_UNCACHED, null); 1518 uid1Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP); 1519 1520 // Return to home. 1521 mTargetContext.startActivity(homeIntent); 1522 uid1Watcher.expect(WatchUidRunner.CMD_CACHED, null); 1523 uid1Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_HEAVY_WEIGHT); 1524 1525 // Again try starting second heavy-weight app to get prompt. 1526 startAndWaitForHeavyWeightSwitcherActivity(activity2Intent); 1527 1528 // Now we'll switch to the new app. 1529 maybeClick(device, new UiSelector().resourceId("android:id/switch_new")); 1530 waitForAppFocus(CANT_SAVE_STATE_2_PACKAGE_NAME, WAIT_TIME); 1531 device.waitForIdle(); 1532 1533 // The original app should now become cached. 1534 uid1Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_RECENT); 1535 1536 // And the new app should start. 1537 uid2Watcher.waitFor(WatchUidRunner.CMD_ACTIVE, null); 1538 uid2Watcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 1539 uid2Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP); 1540 1541 // Make sure the original app is idle for cleanliness 1542 cmd = "am make-uid-idle " + CANT_SAVE_STATE_1_PACKAGE_NAME; 1543 result = SystemUtil.runShellCommand(mInstrumentation, cmd); 1544 uid1Watcher.expect(WatchUidRunner.CMD_IDLE, null); 1545 1546 // Return to home. 1547 mTargetContext.startActivity(homeIntent); 1548 uid2Watcher.waitFor(WatchUidRunner.CMD_CACHED, null); 1549 uid2Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_HEAVY_WEIGHT); 1550 1551 // Try starting the first heavy weight app, but return to the existing second. 1552 startAndWaitForHeavyWeightSwitcherActivity(activity1Intent); 1553 maybeClick(device, new UiSelector().resourceId("android:id/switch_old")); 1554 waitForAppFocus(CANT_SAVE_STATE_2_PACKAGE_NAME, WAIT_TIME); 1555 device.waitForIdle(); 1556 uid2Watcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 1557 uid2Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP); 1558 1559 // Return to home. 1560 mTargetContext.startActivity(homeIntent); 1561 uid2Watcher.waitFor(WatchUidRunner.CMD_CACHED, null); 1562 uid2Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_HEAVY_WEIGHT); 1563 1564 // Again start the first heavy weight app, this time actually switching to it 1565 startAndWaitForHeavyWeightSwitcherActivity(activity1Intent); 1566 maybeClick(device, new UiSelector().resourceId("android:id/switch_new")); 1567 waitForAppFocus(CANT_SAVE_STATE_1_PACKAGE_NAME, WAIT_TIME); 1568 device.waitForIdle(); 1569 1570 // The second app should now become cached. 1571 uid2Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_RECENT); 1572 1573 // And the first app should start. 1574 uid1Watcher.waitFor(WatchUidRunner.CMD_ACTIVE, null); 1575 uid1Watcher.waitFor(WatchUidRunner.CMD_UNCACHED, null); 1576 uid1Watcher.expect(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP); 1577 1578 waitForAppFocus(CANT_SAVE_STATE_1_PACKAGE_NAME, WAIT_TIME); 1579 device.waitForIdle(); 1580 1581 // Exit activity, check to see if we are now cached. 1582 final Intent finishIntent = new Intent(); 1583 finishIntent.setPackage(CANT_SAVE_STATE_1_PACKAGE_NAME); 1584 finishIntent.setAction(ACTION_FINISH); 1585 finishIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 1586 finishIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); 1587 mTargetContext.startActivity(finishIntent); 1588 1589 uid1Watcher.expect(WatchUidRunner.CMD_CACHED, null); 1590 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_RECENT); 1591 1592 // Make both apps idle for cleanliness. 1593 cmd = "am make-uid-idle " + CANT_SAVE_STATE_1_PACKAGE_NAME; 1594 result = SystemUtil.runShellCommand(mInstrumentation, cmd); 1595 cmd = "am make-uid-idle " + CANT_SAVE_STATE_2_PACKAGE_NAME; 1596 result = SystemUtil.runShellCommand(mInstrumentation, cmd); 1597 1598 } finally { 1599 uid2Watcher.finish(); 1600 uid1Watcher.finish(); 1601 } 1602 } 1603 1604 /** 1605 * Test a service binding cycle between two apps, with one of them also running a foreground 1606 * service. The other app should also get an FGS proc state. On stopping the foreground service, 1607 * app should go back to cached state. 1608 * 1609 * @throws Exception 1610 */ 1611 @Test testCycleFgs()1612 public void testCycleFgs() throws Exception { 1613 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 1614 PACKAGE_NAME_APP1, 0); 1615 ApplicationInfo app3Info = mContext.getPackageManager().getApplicationInfo( 1616 PACKAGE_NAME_APP3, 0); 1617 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 1618 WAITFOR_MSEC); 1619 WatchUidRunner uid3Watcher = new WatchUidRunner(mInstrumentation, app3Info.uid, 1620 WAITFOR_MSEC); 1621 1622 try { 1623 CommandReceiver.sendCommand(mContext, 1624 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1625 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1626 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1627 1628 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 1629 PACKAGE_NAME_APP1, PACKAGE_NAME_APP3, 0, null); 1630 1631 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1632 1633 // Create a cycle 1634 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 1635 PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null); 1636 1637 try { 1638 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 1639 WatchUidRunner.STATE_CACHED_EMPTY); 1640 fail("App3 should not be demoted to cached"); 1641 } catch (IllegalStateException ise) { 1642 // Didn't go to cached in spite of cycle. Good! 1643 } 1644 1645 // Stop the foreground service 1646 CommandReceiver.sendCommand(mContext, CommandReceiver 1647 .COMMAND_STOP_FOREGROUND_SERVICE, 1648 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1649 1650 // Check that the app's proc state has fallen 1651 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1652 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1653 } finally { 1654 // Clean up: unbind services to avoid from interferences with other tests 1655 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 1656 PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null); 1657 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 1658 PACKAGE_NAME_APP1, PACKAGE_NAME_APP3, 0, null); 1659 1660 uid1Watcher.finish(); 1661 uid3Watcher.finish(); 1662 } 1663 } 1664 1665 /** 1666 * Test a service binding cycle between three apps, with one of them also running a foreground 1667 * service. The other apps should also get an FGS proc state. On stopping the foreground 1668 * service, app should go back to cached state. 1669 * 1670 * @throws Exception 1671 */ 1672 @Test testCycleFgsTriangle()1673 public void testCycleFgsTriangle() throws Exception { 1674 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 1675 PACKAGE_NAME_APP1, 0); 1676 ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo( 1677 PACKAGE_NAME_APP2, 0); 1678 ApplicationInfo app3Info = mContext.getPackageManager().getApplicationInfo( 1679 PACKAGE_NAME_APP3, 0); 1680 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 1681 WAITFOR_MSEC); 1682 WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid, 1683 WAITFOR_MSEC); 1684 WatchUidRunner uid3Watcher = new WatchUidRunner(mInstrumentation, app3Info.uid, 1685 WAITFOR_MSEC); 1686 1687 try { 1688 CommandReceiver.sendCommand(mContext, 1689 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1690 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1691 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1692 1693 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 1694 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 1695 1696 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1697 1698 // Bind from 2 to 3 1699 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 1700 PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null); 1701 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1702 1703 // Create a cycle 1704 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 1705 PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null); 1706 1707 try { 1708 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 1709 WatchUidRunner.STATE_CACHED_EMPTY); 1710 fail("App3 should not be demoted to cached"); 1711 } catch (IllegalStateException ise) { 1712 // Didn't go to cached in spite of cycle. Good! 1713 } 1714 1715 try { 1716 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 1717 WatchUidRunner.STATE_CACHED_EMPTY); 1718 fail("App2 should not be demoted to cached"); 1719 } catch (IllegalStateException ise) { 1720 // Didn't go to cached in spite of cycle. Good! 1721 } 1722 1723 try { 1724 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 1725 WatchUidRunner.STATE_CACHED_EMPTY); 1726 fail("App1 should not be demoted to cached"); 1727 } catch (IllegalStateException ise) { 1728 // Didn't go to cached in spite of cycle. Good! 1729 } 1730 1731 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 1732 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 1733 1734 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1735 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1736 } finally { 1737 // Clean up: unbind services to avoid from interferences with other tests 1738 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 1739 PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null); 1740 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 1741 PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null); 1742 // Stop the foreground service 1743 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 1744 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1745 1746 uid1Watcher.finish(); 1747 uid2Watcher.finish(); 1748 uid3Watcher.finish(); 1749 } 1750 } 1751 1752 /** 1753 * Test a service binding cycle between three apps, with one of them also running a foreground 1754 * service. The other apps should also get an FGS proc state. On stopping the foreground 1755 * service, app should go back to cached state. 1756 * 1757 * @throws Exception 1758 */ 1759 @Test testCycleFgsTriangleBiDi()1760 public void testCycleFgsTriangleBiDi() throws Exception { 1761 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 1762 PACKAGE_NAME_APP1, 0); 1763 ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo( 1764 PACKAGE_NAME_APP2, 0); 1765 ApplicationInfo app3Info = mContext.getPackageManager().getApplicationInfo( 1766 PACKAGE_NAME_APP3, 0); 1767 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 1768 WAITFOR_MSEC); 1769 WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid, 1770 WAITFOR_MSEC); 1771 WatchUidRunner uid3Watcher = new WatchUidRunner(mInstrumentation, app3Info.uid, 1772 WAITFOR_MSEC); 1773 1774 try { 1775 CommandReceiver.sendCommand(mContext, 1776 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1777 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1778 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1779 1780 // Bind from 1 to 2, 1 to 3 1781 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 1782 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 1783 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 1784 PACKAGE_NAME_APP1, PACKAGE_NAME_APP3, 0, null); 1785 1786 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1787 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1788 1789 // Bind from 2 to 3, 3 to 2, 3 to 1 1790 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 1791 PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null); 1792 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 1793 PACKAGE_NAME_APP3, PACKAGE_NAME_APP2, 0, null); 1794 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 1795 PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null); 1796 1797 try { 1798 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 1799 WatchUidRunner.STATE_CACHED_EMPTY); 1800 fail("App3 should not be demoted to cached"); 1801 } catch (IllegalStateException ise) { 1802 // Didn't go to cached in spite of cycle. Good! 1803 } 1804 1805 // Stop the foreground service 1806 CommandReceiver.sendCommand(mContext, CommandReceiver 1807 .COMMAND_STOP_FOREGROUND_SERVICE, 1808 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1809 1810 // Check that the apps' proc state has fallen 1811 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1812 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1813 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1814 } finally { 1815 // Clean up: unbind services to avoid from interferences with other tests 1816 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 1817 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 1818 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 1819 PACKAGE_NAME_APP1, PACKAGE_NAME_APP3, 0, null); 1820 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 1821 PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null); 1822 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 1823 PACKAGE_NAME_APP3, PACKAGE_NAME_APP2, 0, null); 1824 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 1825 PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null); 1826 1827 uid1Watcher.finish(); 1828 uid2Watcher.finish(); 1829 uid3Watcher.finish(); 1830 } 1831 } 1832 1833 /** 1834 * Test process states for foreground service binding to another app, with and without 1835 * BIND_INCLUDE_CAPABILITIES. With BIND_INCLUDE_CAPABILITIES flag, 1836 * PROCESS_CAPABILITY_FOREGROUND_LOCATION can be passed from client to service. Without 1837 * BIND_INCLUDE_CAPABILITIES flag, PROCESS_CAPABILITY_FOREGROUND_LOCATION can not be passed from 1838 * client to service. 1839 * @throws Exception 1840 */ 1841 @Test testFgsLocationBind()1842 public void testFgsLocationBind() throws Exception { 1843 setupWatchers(3); 1844 1845 try { 1846 // Put Package1 in TOP state, now it gets all capability (because the TOP process 1847 // gets all while-in-use permission (not from FGSL). 1848 CommandReceiver.sendCommand(mContext, 1849 CommandReceiver.COMMAND_START_ACTIVITY, 1850 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1851 mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE, 1852 WatchUidRunner.STATE_TOP, 1853 new Integer(PROCESS_CAPABILITY_FOREGROUND_LOCATION 1854 | PROCESS_CAPABILITY_ALL)); 1855 1856 // Start a FGS 1857 CommandReceiver.sendCommand(mContext, 1858 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1859 mAppInfo[0].packageName, mAppInfo[0].packageName, 0, null); 1860 1861 // Start a FGSL 1862 Bundle bundle = new Bundle(); 1863 bundle.putInt(LocalForegroundServiceLocation.EXTRA_FOREGROUND_SERVICE_TYPE, 1864 ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION); 1865 CommandReceiver.sendCommand(mContext, 1866 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE_LOCATION, 1867 mAppInfo[0].packageName, mAppInfo[0].packageName, 0, bundle); 1868 1869 // Stop the activity. 1870 CommandReceiver.sendCommand(mContext, 1871 CommandReceiver.COMMAND_STOP_ACTIVITY, 1872 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1873 1874 mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE, 1875 WatchUidRunner.STATE_FG_SERVICE, 1876 new Integer(PROCESS_CAPABILITY_NETWORK | PROCESS_CAPABILITY_FOREGROUND_LOCATION 1877 | PROCESS_CAPABILITY_ALL_IMPLICIT)); 1878 1879 // Bind App 0 -> App 1, verify doesn't include capability. 1880 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 1881 mAppInfo[0].packageName, mAppInfo[1].packageName, 0, null); 1882 // Verify app1 does NOT have capability. 1883 mWatchers[1].waitFor(WatchUidRunner.CMD_PROCSTATE, 1884 WatchUidRunner.STATE_FG_SERVICE, 1885 new Integer(PROCESS_CAPABILITY_ALL_IMPLICIT | PROCESS_CAPABILITY_NETWORK)); 1886 1887 // Bind App 0 -> App 2, include capability. 1888 bundle = new Bundle(); 1889 bundle.putInt(CommandReceiver.EXTRA_FLAGS, Context.BIND_INCLUDE_CAPABILITIES); 1890 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 1891 mAppInfo[0].packageName, mAppInfo[2].packageName, 0, bundle); 1892 // Verify app2 has FOREGROUND_LOCATION capability. 1893 mWatchers[2].waitFor(WatchUidRunner.CMD_PROCSTATE, 1894 WatchUidRunner.STATE_FG_SERVICE, 1895 new Integer(PROCESS_CAPABILITY_FOREGROUND_LOCATION | PROCESS_CAPABILITY_NETWORK 1896 | PROCESS_CAPABILITY_ALL_IMPLICIT)); 1897 1898 // Back down to foreground service 1899 CommandReceiver.sendCommand(mContext, 1900 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE_LOCATION, 1901 mAppInfo[0].packageName, mAppInfo[0].packageName, 0, null); 1902 // Verify app0 does NOT have FOREGROUND_LOCATION capability. 1903 mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE, 1904 WatchUidRunner.STATE_FG_SERVICE, 1905 new Integer(PROCESS_CAPABILITY_ALL_IMPLICIT | PROCESS_CAPABILITY_NETWORK)); 1906 1907 // Remove foreground service as well 1908 CommandReceiver.sendCommand(mContext, 1909 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 1910 mAppInfo[0].packageName, mAppInfo[0].packageName, 0, null); 1911 mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE, 1912 WatchUidRunner.STATE_CACHED_EMPTY, 1913 new Integer(PROCESS_CAPABILITY_NONE)); 1914 } finally { 1915 // Clean up: unbind services to avoid from interferences with other tests 1916 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 1917 mAppInfo[0].packageName, mAppInfo[1].packageName, 0, null); 1918 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 1919 mAppInfo[0].packageName, mAppInfo[2].packageName, 0, null); 1920 1921 shutdownWatchers(); 1922 } 1923 } 1924 1925 /** 1926 * Test process states for top app binding with and without BIND_INCLUDE_CAPABILITIES flag. 1927 * Bound app should be TOP w/flag and BTOP without flag. 1928 * @throws Exception 1929 */ 1930 @Test testTopBind()1931 public void testTopBind() throws Exception { 1932 setupWatchers(2); 1933 1934 Activity activity = null; 1935 1936 try { 1937 // This will start an activity in App0 1938 activity = startSubActivity(ScreenOnActivity.class); 1939 1940 // Bind Stub -> App 0, verify doesn't include capability (only BTOP, not TOP) 1941 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 1942 STUB_PACKAGE_NAME, mAppInfo[0].packageName, 0, null); 1943 mWatchers[0].waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_BOUND_TOP, 1944 new Integer(PROCESS_CAPABILITY_NETWORK)); 1945 1946 // Bind Stub -> App 1, include capability (TOP) 1947 Bundle bundle = new Bundle(); 1948 bundle.putInt(CommandReceiver.EXTRA_FLAGS, Context.BIND_INCLUDE_CAPABILITIES); 1949 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 1950 STUB_PACKAGE_NAME, mAppInfo[1].packageName, 0, bundle); 1951 mWatchers[1].waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_BOUND_TOP, 1952 new Integer(PROCESS_CAPABILITY_ALL)); 1953 } finally { 1954 // Clean up: unbind services to avoid from interferences with other tests 1955 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 1956 STUB_PACKAGE_NAME, mAppInfo[0].packageName, 0, null); 1957 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 1958 STUB_PACKAGE_NAME, mAppInfo[1].packageName, 0, null); 1959 1960 shutdownWatchers(); 1961 if (activity != null) { 1962 activity.finish(); 1963 } 1964 } 1965 } 1966 startSubActivity(Class<T> activityClass)1967 private final <T extends Activity> Activity startSubActivity(Class<T> activityClass) { 1968 final Instrumentation.ActivityResult result = new Instrumentation.ActivityResult( 1969 0, new Intent()); 1970 final Instrumentation.ActivityMonitor monitor = new Instrumentation.ActivityMonitor( 1971 activityClass.getName(), result, false); 1972 mInstrumentation.addMonitor(monitor); 1973 launchActivity(STUB_PACKAGE_NAME, activityClass, null); 1974 return monitor.waitForActivity(); 1975 } 1976 1977 @Test testCycleTop()1978 public void testCycleTop() throws Exception { 1979 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 1980 PACKAGE_NAME_APP1, 0); 1981 ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo( 1982 PACKAGE_NAME_APP2, 0); 1983 ApplicationInfo app3Info = mContext.getPackageManager().getApplicationInfo( 1984 PACKAGE_NAME_APP3, 0); 1985 1986 PermissionUtils.grantPermission( 1987 PACKAGE_NAME_APP1, android.Manifest.permission.PACKAGE_USAGE_STATS); 1988 PermissionUtils.grantPermission( 1989 PACKAGE_NAME_APP2, android.Manifest.permission.PACKAGE_USAGE_STATS); 1990 PermissionUtils.grantPermission( 1991 PACKAGE_NAME_APP3, android.Manifest.permission.PACKAGE_USAGE_STATS); 1992 1993 UidImportanceListener uid1Listener = new UidImportanceListener(mContext, 1994 app1Info.uid, IMPORTANCE_VISIBLE, 1995 WAITFOR_MSEC); 1996 uid1Listener.register(); 1997 1998 UidImportanceListener uid1ServiceListener = new UidImportanceListener(mContext, 1999 app1Info.uid, IMPORTANCE_CACHED, 2000 WAITFOR_MSEC); 2001 uid1ServiceListener.register(); 2002 2003 UidImportanceListener uid2Listener = new UidImportanceListener(mContext, 2004 app2Info.uid, IMPORTANCE_VISIBLE, 2005 WAITFOR_MSEC); 2006 uid2Listener.register(); 2007 2008 UidImportanceListener uid2ServiceListener = new UidImportanceListener(mContext, 2009 app2Info.uid, IMPORTANCE_CACHED, 2010 WAITFOR_MSEC); 2011 uid2ServiceListener.register(); 2012 2013 UidImportanceListener uid3Listener = new UidImportanceListener(mContext, 2014 app3Info.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE, 2015 WAITFOR_MSEC); 2016 uid3Listener.register(); 2017 2018 UidImportanceListener uid3ServiceListener = new UidImportanceListener(mContext, 2019 app3Info.uid, IMPORTANCE_CACHED, 2020 WAITFOR_MSEC); 2021 uid3ServiceListener.register(); 2022 2023 Activity activity = null; 2024 2025 try { 2026 // Start an activity 2027 activity = startSubActivity(ScreenOnActivity.class); 2028 2029 // Start a FGS in app2 2030 CommandReceiver.sendCommand(mContext, 2031 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, PACKAGE_NAME_APP2, 2032 PACKAGE_NAME_APP2, 0, null); 2033 2034 uid2Listener.waitForValue( 2035 IMPORTANCE_FOREGROUND_SERVICE, 2036 IMPORTANCE_FOREGROUND_SERVICE); 2037 2038 // Bind from TOP to the service in app1 2039 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 2040 STUB_PACKAGE_NAME, PACKAGE_NAME_APP1, 0, null); 2041 2042 uid1Listener.waitForValue(IMPORTANCE_FOREGROUND, 2043 IMPORTANCE_FOREGROUND_SERVICE); 2044 2045 // Bind from app1 to a service in app2 2046 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 2047 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 2048 2049 // Bind from app2 to a service in app3 2050 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 2051 PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null); 2052 2053 uid3Listener.waitForValue(IMPORTANCE_FOREGROUND, 2054 IMPORTANCE_FOREGROUND_SERVICE); 2055 2056 // Create a cycle 2057 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 2058 PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null); 2059 2060 try { 2061 uid3Listener.waitForValue(IMPORTANCE_CACHED, 2062 IMPORTANCE_CACHED); 2063 fail("App3 should not be demoted to cached, expecting FGS"); 2064 } catch (IllegalStateException e) { 2065 // Didn't go to cached in spite of cycle. Good! 2066 } 2067 2068 // Unbind from the TOP app 2069 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 2070 STUB_PACKAGE_NAME, PACKAGE_NAME_APP1, 0, null); 2071 2072 // Check that the apps' proc state is FOREGROUND_SERVICE 2073 uid2Listener.waitForValue( 2074 IMPORTANCE_FOREGROUND_SERVICE, 2075 IMPORTANCE_FOREGROUND_SERVICE); 2076 2077 // Stop the foreground service 2078 CommandReceiver.sendCommand(mContext, CommandReceiver 2079 .COMMAND_STOP_FOREGROUND_SERVICE, 2080 PACKAGE_NAME_APP2, PACKAGE_NAME_APP2, 0, null); 2081 2082 // Check that the apps fall down to cached state 2083 uid1ServiceListener.waitForValue( 2084 IMPORTANCE_CACHED, 2085 IMPORTANCE_CACHED); 2086 2087 uid2ServiceListener.waitForValue( 2088 IMPORTANCE_CACHED, 2089 IMPORTANCE_CACHED); 2090 2091 uid3ServiceListener.waitForValue( 2092 IMPORTANCE_CACHED, 2093 IMPORTANCE_CACHED); 2094 } finally { 2095 // Clean up: unbind services to avoid from interferences with other tests 2096 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 2097 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 2098 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 2099 PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null); 2100 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 2101 PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null); 2102 2103 uid1Listener.unregister(); 2104 uid1ServiceListener.unregister(); 2105 uid2Listener.unregister(); 2106 uid2ServiceListener.unregister(); 2107 uid3Listener.unregister(); 2108 uid3ServiceListener.unregister(); 2109 if (activity != null) { 2110 activity.finish(); 2111 } 2112 } 2113 } 2114 2115 @Test testCycleFgAppAndAlert()2116 public void testCycleFgAppAndAlert() throws Exception { 2117 ApplicationInfo stubInfo = mContext.getPackageManager().getApplicationInfo( 2118 STUB_PACKAGE_NAME, 0); 2119 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 2120 PACKAGE_NAME_APP1, 0); 2121 ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo( 2122 PACKAGE_NAME_APP2, 0); 2123 ApplicationInfo app3Info = mContext.getPackageManager().getApplicationInfo( 2124 PACKAGE_NAME_APP3, 0); 2125 2126 PermissionUtils.grantPermission( 2127 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS); 2128 PermissionUtils.grantPermission( 2129 PACKAGE_NAME_APP1, android.Manifest.permission.PACKAGE_USAGE_STATS); 2130 PermissionUtils.grantPermission( 2131 PACKAGE_NAME_APP2, android.Manifest.permission.PACKAGE_USAGE_STATS); 2132 PermissionUtils.grantPermission( 2133 PACKAGE_NAME_APP3, android.Manifest.permission.PACKAGE_USAGE_STATS); 2134 2135 UidImportanceListener stubListener = new UidImportanceListener(mContext, 2136 stubInfo.uid, ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE, 2137 WAITFOR_MSEC); 2138 stubListener.register(); 2139 2140 UidImportanceListener uid1Listener = new UidImportanceListener(mContext, 2141 app1Info.uid, IMPORTANCE_VISIBLE, 2142 WAITFOR_MSEC); 2143 uid1Listener.register(); 2144 2145 UidImportanceListener uid2Listener = new UidImportanceListener(mContext, 2146 app2Info.uid, IMPORTANCE_VISIBLE, 2147 WAITFOR_MSEC); 2148 uid2Listener.register(); 2149 2150 UidImportanceListener uid3Listener = new UidImportanceListener(mContext, 2151 app3Info.uid, IMPORTANCE_VISIBLE, 2152 WAITFOR_MSEC); 2153 uid3Listener.register(); 2154 2155 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 2156 WAITFOR_MSEC); 2157 WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid, 2158 WAITFOR_MSEC); 2159 WatchUidRunner uid3Watcher = new WatchUidRunner(mInstrumentation, app3Info.uid, 2160 WAITFOR_MSEC); 2161 2162 try { 2163 // Stub app should have been in foreground since it's being instrumented. 2164 2165 PermissionUtils.grantPermission( 2166 STUB_PACKAGE_NAME, android.Manifest.permission.SYSTEM_ALERT_WINDOW); 2167 // Show an alert on app0 2168 CommandReceiver.sendCommand(mContext, 2169 CommandReceiver.COMMAND_START_ALERT_SERVICE, STUB_PACKAGE_NAME, 2170 STUB_PACKAGE_NAME, 0, null); 2171 2172 // Start a FGS in app2 2173 CommandReceiver.sendCommand(mContext, 2174 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, PACKAGE_NAME_APP2, 2175 PACKAGE_NAME_APP2, 0, null); 2176 2177 uid2Listener.waitForValue(IMPORTANCE_FOREGROUND_SERVICE, 2178 IMPORTANCE_FOREGROUND_SERVICE); 2179 2180 // Bind from app0 to a service in app1 2181 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 2182 STUB_PACKAGE_NAME, PACKAGE_NAME_APP1, 0, null); 2183 2184 // Bind from app2 to a service in app1 2185 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 2186 PACKAGE_NAME_APP2, PACKAGE_NAME_APP1, 0, null); 2187 2188 // Bind from app3 to a service in app1 2189 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 2190 PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null); 2191 2192 // Create a cycle 2193 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 2194 PACKAGE_NAME_APP1, PACKAGE_NAME_APP3, 0, null); 2195 2196 uid1Listener.waitForValue(IMPORTANCE_FOREGROUND_SERVICE, 2197 IMPORTANCE_FOREGROUND_SERVICE); 2198 uid3Listener.waitForValue(IMPORTANCE_FOREGROUND_SERVICE, 2199 IMPORTANCE_FOREGROUND_SERVICE); 2200 2201 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 2202 STUB_PACKAGE_NAME, PACKAGE_NAME_APP1, 0, null); 2203 2204 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 2205 PACKAGE_NAME_APP2, PACKAGE_NAME_APP1, 0, null); 2206 2207 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 2208 PACKAGE_NAME_APP3, PACKAGE_NAME_APP1, 0, null); 2209 2210 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 2211 PACKAGE_NAME_APP1, PACKAGE_NAME_APP3, 0, null); 2212 2213 // Stop the foreground service 2214 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 2215 PACKAGE_NAME_APP2, PACKAGE_NAME_APP2, 0, null); 2216 2217 // hide the alert 2218 CommandReceiver.sendCommand(mContext, 2219 CommandReceiver.COMMAND_STOP_ALERT_SERVICE, STUB_PACKAGE_NAME, 2220 STUB_PACKAGE_NAME, 0, null); 2221 2222 // Check that the apps' proc state has fallen 2223 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 2224 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 2225 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 2226 } finally { 2227 stubListener.unregister(); 2228 uid1Listener.unregister(); 2229 uid2Listener.unregister(); 2230 uid3Listener.unregister(); 2231 uid1Watcher.finish(); 2232 uid2Watcher.finish(); 2233 uid3Watcher.finish(); 2234 } 2235 } 2236 2237 /** 2238 * Test FGS compatibility with START_STICKY flag. 2239 * @throws Exception 2240 */ 2241 @Test testFgsSticky1()2242 public void testFgsSticky1() throws Exception { 2243 // For START_STICKY, service is restarted, Service.onStartCommand is called with a null 2244 // intent. 2245 testFgsStickyInternal(Service.START_STICKY, ACTION_RESTART_FGS_STICKY_RESULT, 2246 (uidWatcher, waiter) -> { 2247 // After restart, the FGS still has its while-in-use capabilities. 2248 uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 2249 WatchUidRunner.STATE_FG_SERVICE, 2250 new Integer(PROCESS_CAPABILITY_ALL)); 2251 waiter.doWait(WAITFOR_MSEC); 2252 }); 2253 } 2254 2255 /** 2256 * Test FGS compatibility with START_REDELIVER_INTENT flag. 2257 * @throws Exception 2258 */ 2259 @Test testFgsSticky2()2260 public void testFgsSticky2() throws Exception { 2261 // For START_REDELIVER_INTENT, service is restarted, Service.onStartCommand is called with 2262 // the same intent as previous service start. 2263 testFgsStickyInternal(Service.START_REDELIVER_INTENT, ACTION_START_FGS_RESULT, 2264 (uidWatcher, waiter) -> { 2265 // After restart, the FGS still has its while-in-use capabilities. 2266 uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 2267 WatchUidRunner.STATE_FG_SERVICE, 2268 new Integer(PROCESS_CAPABILITY_ALL)); 2269 waiter.doWait(WAITFOR_MSEC); 2270 }); 2271 } 2272 2273 /** 2274 * Test FGS compatibility with START_NOT_STICKY flag. 2275 * @throws Exception 2276 */ 2277 @Test testFgsSticky3()2278 public void testFgsSticky3() throws Exception { 2279 // For START_NOT_STICKY, service does not restart and Service.onStartCommand is not called 2280 // again. 2281 testFgsStickyInternal(Service.START_NOT_STICKY, ACTION_RESTART_FGS_STICKY_RESULT, 2282 (uidWatcher, waiter) -> { 2283 try { 2284 uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 2285 WatchUidRunner.STATE_FG_SERVICE); 2286 fail("Not-Sticky service should not restart after kill"); 2287 } catch (Exception e) { 2288 } 2289 try { 2290 waiter.doWait(WAITFOR_MSEC); 2291 fail("Not-Sticky service should not call onStartCommand after kill"); 2292 } catch (Exception e) { 2293 } 2294 }); 2295 2296 testFgsStickyInternal(Service.START_NOT_STICKY, ACTION_START_FGS_RESULT, 2297 (uidWatcher, waiter) -> { 2298 try { 2299 uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 2300 WatchUidRunner.STATE_FG_SERVICE); 2301 fail("Not-Sticky service should not restart after kill"); 2302 } catch (Exception e) { 2303 } 2304 try { 2305 waiter.doWait(WAITFOR_MSEC); 2306 fail("Not-Sticky service should not call onStartCommand after kill"); 2307 } catch (Exception e) { 2308 } 2309 }); 2310 } 2311 2312 @Test testForegroundService_malformedNotificationExtras()2313 public void testForegroundService_malformedNotificationExtras() throws Exception { 2314 PermissionUtils.grantPermission( 2315 STUB_PACKAGE_NAME, android.Manifest.permission.PACKAGE_USAGE_STATS); 2316 // Use default timeout value 5000 2317 final ServiceProcessController controller = new ServiceProcessController(mContext, 2318 mInstrumentation, STUB_PACKAGE_NAME, mAllProcesses); 2319 2320 ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo( 2321 SIMPLE_PACKAGE_NAME, 0); 2322 UidImportanceListener uidGoneListener = new UidImportanceListener(mContext, 2323 appInfo.uid, IMPORTANCE_CACHED, WAIT_TIME); 2324 uidGoneListener.register(); 2325 2326 ActivityManager am = mContext.getSystemService(ActivityManager.class); 2327 2328 try { 2329 controller.ensureProcessGone(); 2330 2331 // Do initial setup. 2332 controller.makeUidIdle(); 2333 controller.removeFromWhitelist(); 2334 controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "allow"); 2335 2336 // Put app on whitelist, to allow service to run. 2337 controller.addToWhitelist(); 2338 2339 // Add a bad extra to the FGS notification and try to start the service 2340 // keep key in sync with com.android.cts.launcherapps.simpleapp.SimpleService 2341 mServiceStartForegroundIntent.putExtra("NotifExtras", true); 2342 mContext.startService(mServiceStartForegroundIntent); 2343 2344 // Make sure we crashed the process 2345 uidGoneListener.waitForValue(IMPORTANCE_GONE, IMPORTANCE_GONE); 2346 assertEquals(IMPORTANCE_GONE, am.getPackageImportance(SIMPLE_PACKAGE_NAME)); 2347 } finally { 2348 mContext.stopService(mServiceStartForegroundIntent); 2349 controller.cleanup(); 2350 controller.setAppOpMode(AppOpsManager.OPSTR_START_FOREGROUND, "ignore"); 2351 controller.removeFromWhitelist(); 2352 } 2353 } 2354 testFgsStickyInternal(int stickyFlag, String waitForBroadcastAction, BiConsumer<WatchUidRunner, WaitForBroadcast> checkKillResult)2355 private void testFgsStickyInternal(int stickyFlag, String waitForBroadcastAction, 2356 BiConsumer<WatchUidRunner, WaitForBroadcast> checkKillResult) throws Exception { 2357 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 2358 PACKAGE_NAME_APP1, 0); 2359 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 2360 WAITFOR_MSEC); 2361 AmMonitor monitor = new AmMonitor(mInstrumentation, 2362 new String[]{AmMonitor.WAIT_FOR_EARLY_ANR, AmMonitor.WAIT_FOR_ANR}); 2363 try { 2364 // Start an activity in app1 to put app1 in TOP state, so the FGS it started can have 2365 // while-in-use capabilities. 2366 CommandReceiver.sendCommand(mContext, 2367 CommandReceiver.COMMAND_START_ACTIVITY, 2368 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 2369 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 2370 WatchUidRunner.STATE_TOP, 2371 new Integer(PROCESS_CAPABILITY_ALL)); 2372 2373 WaitForBroadcast waiter = new WaitForBroadcast(mInstrumentation.getTargetContext()); 2374 waiter.prepare(ACTION_START_FGS_RESULT); 2375 Bundle extras = new Bundle(); 2376 extras.putInt(LocalForegroundServiceSticky.STICKY_FLAG, stickyFlag); 2377 CommandReceiver.sendCommand(mContext, 2378 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE_STICKY, 2379 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, extras); 2380 2381 // Launch home activity, so the activity in app1 will be stopped, app1 now only has FGS, 2382 // we're not "finishing" the activity because removing a task could result in service 2383 // restart. 2384 waitForAppFocus(PACKAGE_NAME_APP1,WAITFOR_MSEC); 2385 final Intent homeIntent = new Intent(); 2386 homeIntent.setAction(Intent.ACTION_MAIN); 2387 homeIntent.addCategory(Intent.CATEGORY_HOME); 2388 homeIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2389 mTargetContext.startActivity(homeIntent); 2390 2391 // The FGS has all while-in-use capabilities. 2392 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE, 2393 new Integer(PROCESS_CAPABILITY_ALL)); 2394 waiter.doWait(WAITFOR_MSEC); 2395 2396 waiter = new WaitForBroadcast(mInstrumentation.getTargetContext()); 2397 waiter.prepare(waitForBroadcastAction); 2398 CtsAppTestUtils.executeShellCmd(mInstrumentation, 2399 "am crash " + PACKAGE_NAME_APP1); 2400 monitor.waitFor(AmMonitor.WAIT_FOR_CRASHED, WAITFOR_MSEC); 2401 monitor.sendCommand(AmMonitor.CMD_KILL); 2402 checkKillResult.accept(uid1Watcher, waiter); 2403 } finally { 2404 final ActivityManager am = mContext.getSystemService(ActivityManager.class); 2405 SystemUtil.runWithShellPermissionIdentity(() -> { 2406 am.forceStopPackage(PACKAGE_NAME_APP1); 2407 }); 2408 uid1Watcher.finish(); 2409 monitor.finish(); 2410 } 2411 } 2412 2413 // Copied from android.test.InstrumentationTestCase 2414 /** 2415 * Utility method for launching an activity. 2416 * 2417 * <p>The {@link Intent} used to launch the Activity is: 2418 * action = {@link Intent#ACTION_MAIN} 2419 * extras = null, unless a custom bundle is provided here 2420 * All other fields are null or empty. 2421 * 2422 * <p><b>NOTE:</b> The parameter <i>pkg</i> must refer to the package identifier of the 2423 * package hosting the activity to be launched, which is specified in the AndroidManifest.xml 2424 * file. This is not necessarily the same as the java package name. 2425 * 2426 * @param pkg The package hosting the activity to be launched. 2427 * @param activityCls The activity class to launch. 2428 * @param extras Optional extra stuff to pass to the activity. 2429 * @return The activity, or null if non launched. 2430 */ launchActivity( String pkg, Class<T> activityCls, Bundle extras)2431 public final <T extends Activity> T launchActivity( 2432 String pkg, 2433 Class<T> activityCls, 2434 Bundle extras) { 2435 Intent intent = new Intent(Intent.ACTION_MAIN); 2436 if (extras != null) { 2437 intent.putExtras(extras); 2438 } 2439 return launchActivityWithIntent(pkg, activityCls, intent); 2440 } 2441 2442 // Copied from android.test.InstrumentationTestCase 2443 /** 2444 * Utility method for launching an activity with a specific Intent. 2445 * 2446 * <p><b>NOTE:</b> The parameter <i>pkg</i> must refer to the package identifier of the 2447 * package hosting the activity to be launched, which is specified in the AndroidManifest.xml 2448 * file. This is not necessarily the same as the java package name. 2449 * 2450 * @param pkg The package hosting the activity to be launched. 2451 * @param activityCls The activity class to launch. 2452 * @param intent The intent to launch with 2453 * @return The activity, or null if non launched. 2454 */ 2455 @SuppressWarnings("unchecked") launchActivityWithIntent( String pkg, Class<T> activityCls, Intent intent)2456 public final <T extends Activity> T launchActivityWithIntent( 2457 String pkg, 2458 Class<T> activityCls, 2459 Intent intent) { 2460 intent.setClassName(pkg, activityCls.getName()); 2461 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 2462 T activity = (T) mInstrumentation.startActivitySync(intent); 2463 mInstrumentation.waitForIdleSync(); 2464 return activity; 2465 } 2466 } 2467