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