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