1 /* 2 * Copyright (C) 2019 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.stubs.LocalForegroundService.ACTION_START_FGS_RESULT; 26 import static android.app.stubs.LocalForegroundServiceLocation.ACTION_START_FGSL_RESULT; 27 import static android.os.PowerExemptionManager.REASON_PUSH_MESSAGING; 28 import static android.os.PowerExemptionManager.REASON_PUSH_MESSAGING_OVER_QUOTA; 29 import static android.os.PowerExemptionManager.REASON_UNKNOWN; 30 import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED; 31 import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED; 32 import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_NONE; 33 34 import static com.android.compatibility.common.util.SystemUtil.runShellCommand; 35 import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity; 36 37 import static junit.framework.Assert.assertNotNull; 38 import static junit.framework.Assert.assertNull; 39 import static junit.framework.Assert.assertTrue; 40 import static junit.framework.Assert.fail; 41 42 import static org.junit.Assume.assumeFalse; 43 44 import android.accessibilityservice.AccessibilityService; 45 import android.app.ActivityManager; 46 import android.app.BroadcastOptions; 47 import android.app.ForegroundServiceStartNotAllowedException; 48 import android.app.Instrumentation; 49 import android.app.cts.android.app.cts.tools.WaitForBroadcast; 50 import android.app.cts.android.app.cts.tools.WatchUidRunner; 51 import android.app.stubs.CommandReceiver; 52 import android.app.stubs.LocalForegroundService; 53 import android.app.stubs.LocalForegroundServiceLocation; 54 import android.app.stubs.shared.NotificationHelper; 55 import android.app.stubs.shared.TestNotificationListener; 56 import android.content.ComponentName; 57 import android.content.Context; 58 import android.content.Intent; 59 import android.content.ServiceConnection; 60 import android.content.pm.ApplicationInfo; 61 import android.content.pm.ServiceInfo; 62 import android.media.session.MediaController; 63 import android.media.session.MediaSessionManager; 64 import android.os.Bundle; 65 import android.os.IBinder; 66 import android.os.PowerExemptionManager; 67 import android.os.RemoteCallback; 68 import android.os.SystemClock; 69 import android.permission.cts.PermissionUtils; 70 import android.platform.test.annotations.AsbSecurityTest; 71 import android.platform.test.annotations.Presubmit; 72 import android.platform.test.annotations.RequiresFlagsDisabled; 73 import android.platform.test.annotations.RequiresFlagsEnabled; 74 import android.platform.test.flag.junit.CheckFlagsRule; 75 import android.platform.test.flag.junit.DeviceFlagsValueProvider; 76 import android.provider.DeviceConfig; 77 import android.provider.Settings; 78 import android.server.wm.settings.SettingsSession; 79 import android.util.Log; 80 81 import androidx.test.InstrumentationRegistry; 82 import androidx.test.ext.junit.runners.AndroidJUnit4; 83 import androidx.test.filters.LargeTest; 84 import androidx.test.uiautomator.UiDevice; 85 86 import com.android.compatibility.common.util.AmUtils; 87 import com.android.compatibility.common.util.SystemUtil; 88 import com.android.compatibility.common.util.TestUtils; 89 import com.android.compatibility.common.util.UserHelper; 90 import com.android.server.am.Flags; 91 92 import org.junit.After; 93 import org.junit.Before; 94 import org.junit.BeforeClass; 95 import org.junit.Ignore; 96 import org.junit.Rule; 97 import org.junit.Test; 98 import org.junit.runner.RunWith; 99 100 import java.util.List; 101 import java.util.concurrent.CountDownLatch; 102 import java.util.concurrent.TimeUnit; 103 104 @RunWith(AndroidJUnit4.class) 105 public class ActivityManagerFgsBgStartTest { 106 private static final String TAG = ActivityManagerFgsBgStartTest.class.getName(); 107 108 static final String STUB_PACKAGE_NAME = "android.app.stubs"; 109 static final String PACKAGE_NAME_APP1 = "com.android.app1"; 110 static final String PACKAGE_NAME_APP2 = "com.android.app2"; 111 static final String PACKAGE_NAME_APP3 = "com.android.app3"; 112 113 private static final String KEY_DEFAULT_FGS_STARTS_RESTRICTION_ENABLED = 114 "default_fgs_starts_restriction_enabled"; 115 116 private static final String KEY_FGS_START_FOREGROUND_TIMEOUT = 117 "fgs_start_foreground_timeout"; 118 119 private static final String KEY_PUSH_MESSAGING_OVER_QUOTA_BEHAVIOR = 120 "push_messaging_over_quota_behavior"; 121 122 // REASON_ALARM_MANAGER_ALARM_CLOCK is not exposed by PowerExemptionManager, hard code its value 123 // here. 124 private static final int REASON_ALARM_MANAGER_ALARM_CLOCK = 301; 125 private static final int DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS = 10 * 1000; 126 127 public static final Integer LOCAL_SERVICE_PROCESS_CAPABILITY = new Integer( 128 PROCESS_CAPABILITY_FOREGROUND_CAMERA 129 | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE 130 | PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK 131 | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK); 132 133 private static final int PROCESS_CAPABILITY_ALL = PROCESS_CAPABILITY_FOREGROUND_LOCATION 134 | PROCESS_CAPABILITY_FOREGROUND_CAMERA 135 | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE 136 | PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK 137 | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK; 138 139 static final int WAITFOR_MSEC = 10000; 140 141 private static final int TEMP_ALLOWLIST_DURATION_MS = 2000; 142 143 private static final String[] PACKAGE_NAMES = { 144 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, PACKAGE_NAME_APP3 145 }; 146 147 private final UserHelper mUserHelper = new UserHelper(); 148 149 private Context mContext; 150 private Instrumentation mInstrumentation; 151 private Context mTargetContext; 152 private int mTestRunningUserId; 153 154 private int mOrigDeviceDemoMode = 0; 155 private boolean mOrigFgsTypeStartPermissionEnforcement; 156 157 @Rule 158 public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); 159 160 @BeforeClass setupClass()161 public static void setupClass() throws Exception { 162 AmUtils.waitForBroadcastBarrier(); 163 } 164 165 @Before setUp()166 public void setUp() throws Exception { 167 mInstrumentation = InstrumentationRegistry.getInstrumentation(); 168 mContext = mInstrumentation.getContext(); 169 mTargetContext = mInstrumentation.getTargetContext(); 170 mTestRunningUserId = mTargetContext.getUserId(); 171 for (int i = 0; i < PACKAGE_NAMES.length; ++i) { 172 CtsAppTestUtils.makeUidIdle(mInstrumentation, PACKAGE_NAMES[i]); 173 // The manifest file gives test app SYSTEM_ALERT_WINDOW permissions, which also exempt 174 // the app from BG-FGS-launch restriction. Remove SYSTEM_ALERT_WINDOW permission to test 175 // other BG-FGS-launch exemptions. 176 allowBgActivityStart(PACKAGE_NAMES[i], false); 177 CtsAppTestUtils.clearBadProcess(PACKAGE_NAMES[i], mTestRunningUserId); 178 } 179 mOrigFgsTypeStartPermissionEnforcement = toggleBgFgsTypeStartPermissionEnforcement(false); 180 CtsAppTestUtils.turnScreenOn(mInstrumentation, mContext); 181 cleanupResiduals(); 182 enableFgsRestriction(true, true, null); 183 // Press home key to ensure stopAppSwitches is called so the grace period of 184 // the background start will be ignored if there's any. 185 UiDevice.getInstance(mInstrumentation).pressHome(); 186 AmUtils.waitForBroadcastBarrier(); 187 } 188 189 @After tearDown()190 public void tearDown() throws Exception { 191 for (int i = 0; i < PACKAGE_NAMES.length; ++i) { 192 CtsAppTestUtils.makeUidIdle(mInstrumentation, PACKAGE_NAMES[i]); 193 allowBgActivityStart(PACKAGE_NAMES[i], true); 194 } 195 toggleBgFgsTypeStartPermissionEnforcement(mOrigFgsTypeStartPermissionEnforcement); 196 cleanupResiduals(); 197 enableFgsRestriction(true, true, null); 198 for (String packageName : PACKAGE_NAMES) { 199 resetFgsSawRestrictionEnabled(packageName); 200 resetFgsRestriction(packageName); 201 } 202 } 203 cleanupResiduals()204 private void cleanupResiduals() { 205 // Stop all the packages to avoid residual impact 206 final ActivityManager am = mContext.getSystemService(ActivityManager.class); 207 for (int i = 0; i < PACKAGE_NAMES.length; i++) { 208 final String pkgName = PACKAGE_NAMES[i]; 209 SystemUtil.runWithShellPermissionIdentity(() -> { 210 am.forceStopPackage(pkgName); 211 }); 212 } 213 // Make sure we are in Home screen 214 mInstrumentation.getUiAutomation().performGlobalAction( 215 AccessibilityService.GLOBAL_ACTION_HOME); 216 } 217 toggleBgFgsTypeStartPermissionEnforcement(Boolean enforce)218 static boolean toggleBgFgsTypeStartPermissionEnforcement(Boolean enforce) { 219 final String namespaceActivityManager = "activity_manager"; 220 final String keygFgsTypeStartPermissionEnforcement = "fgs_type_fg_perm_enforcement_flag"; 221 final boolean[] origValue = new boolean[1]; 222 223 SystemUtil.runWithShellPermissionIdentity(() -> { 224 origValue[0] = DeviceConfig.getBoolean(namespaceActivityManager, 225 keygFgsTypeStartPermissionEnforcement, true); 226 DeviceConfig.setProperty(namespaceActivityManager, 227 keygFgsTypeStartPermissionEnforcement, enforce.toString(), false); 228 }); 229 return origValue[0]; 230 } 231 232 /** 233 * APP1 is in BG state, it can start FGSL, but it won't get location capability. 234 * APP1 is in TOP state, it gets location capability. 235 * @throws Exception 236 */ 237 @Presubmit 238 @Test testFgsLocationStartFromBG()239 public void testFgsLocationStartFromBG() throws Exception { 240 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 241 PACKAGE_NAME_APP1, 0); 242 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 243 WAITFOR_MSEC, PROCESS_CAPABILITY_ALL); 244 245 try { 246 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGSL_RESULT); 247 // APP1 is in BG state, Start FGSL in APP1, it won't get location capability. 248 Bundle bundle = new Bundle(); 249 bundle.putInt(LocalForegroundServiceLocation.EXTRA_FOREGROUND_SERVICE_TYPE, 250 ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION 251 | ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA 252 | ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE); 253 final Bundle bundle2 = new Bundle(); 254 bundle2.putInt(LocalForegroundServiceLocation.EXTRA_FOREGROUND_SERVICE_TYPE, 255 ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA 256 | ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE); 257 // start FGSL. 258 enableFgsRestriction(false, true, null); 259 CommandReceiver.sendCommand(mContext, 260 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE_LOCATION, 261 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, bundle); 262 // APP1 is in FGS state, but won't get location capability. 263 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 264 WatchUidRunner.STATE_FG_SERVICE, 265 new Integer(PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK 266 | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK)); 267 waiter.doWait(WAITFOR_MSEC); 268 // stop FGSL 269 CommandReceiver.sendCommand(mContext, 270 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE_LOCATION, 271 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 272 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 273 WatchUidRunner.STATE_CACHED_EMPTY, 274 new Integer(PROCESS_CAPABILITY_NONE)); 275 276 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 277 // APP1 is in FGS state, 278 CommandReceiver.sendCommand(mContext, 279 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 280 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, bundle2); 281 // start FGSL in app1, it won't get location capability. 282 CommandReceiver.sendCommand(mContext, 283 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE_LOCATION, 284 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, bundle); 285 // APP1 is in STATE_FG_SERVICE, but won't get location capability. 286 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 287 WatchUidRunner.STATE_FG_SERVICE, 288 new Integer(PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK 289 | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK)); 290 waiter.doWait(WAITFOR_MSEC); 291 // stop FGS. 292 CommandReceiver.sendCommand(mContext, 293 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 294 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 295 // stop FGSL. 296 CommandReceiver.sendCommand(mContext, 297 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE_LOCATION, 298 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 299 300 // Put APP1 in TOP state, now it gets location capability (because the TOP process 301 // gets all while-in-use permission (not from FGSL). 302 allowBgActivityStart(PACKAGE_NAME_APP1, true); 303 CommandReceiver.sendCommand(mContext, 304 CommandReceiver.COMMAND_START_ACTIVITY, 305 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 306 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 307 WatchUidRunner.STATE_TOP, 308 new Integer(PROCESS_CAPABILITY_ALL)); 309 310 waiter = createBroadcastWaiter(ACTION_START_FGSL_RESULT); 311 // APP1 is in TOP state, start the FGSL in APP1, it will get location capability. 312 CommandReceiver.sendCommand(mContext, 313 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE_LOCATION, 314 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, bundle); 315 // Stop the activity. 316 CommandReceiver.sendCommand(mContext, 317 CommandReceiver.COMMAND_STOP_ACTIVITY, 318 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 319 // The FGSL still has location capability because it is started from TOP. 320 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 321 WatchUidRunner.STATE_FG_SERVICE, 322 new Integer(PROCESS_CAPABILITY_ALL)); 323 waiter.doWait(WAITFOR_MSEC); 324 // Stop FGSL. 325 CommandReceiver.sendCommand(mContext, 326 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE_LOCATION, 327 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 328 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 329 WatchUidRunner.STATE_CACHED_EMPTY, 330 new Integer(PROCESS_CAPABILITY_NONE)); 331 } finally { 332 uid1Watcher.finish(); 333 } 334 } 335 336 /** 337 * APP1 is in BG state, it can start FGSL in APP2, but the FGS won't get location 338 * capability. 339 * APP1 is in TOP state, it can start FGSL in APP2, FGSL gets location capability. 340 * @throws Exception 341 */ 342 @Presubmit 343 @Test testFgsLocationStartFromBGTwoProcesses()344 public void testFgsLocationStartFromBGTwoProcesses() throws Exception { 345 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 346 PACKAGE_NAME_APP1, 0); 347 ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo( 348 PACKAGE_NAME_APP2, 0); 349 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 350 WAITFOR_MSEC, PROCESS_CAPABILITY_ALL); 351 WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid, 352 WAITFOR_MSEC, PROCESS_CAPABILITY_ALL); 353 354 try { 355 // APP1 is in BG state, start FGSL in APP2. 356 Bundle bundle = new Bundle(); 357 bundle.putInt(LocalForegroundServiceLocation.EXTRA_FOREGROUND_SERVICE_TYPE, 358 ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION 359 | ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA 360 | ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE); 361 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGSL_RESULT); 362 enableFgsRestriction(false, true, null); 363 CommandReceiver.sendCommand(mContext, 364 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE_LOCATION, 365 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, bundle); 366 // APP2 won't have location capability because APP1 is not in TOP state. 367 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 368 WatchUidRunner.STATE_FG_SERVICE, 369 new Integer(PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK 370 | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK)); 371 waiter.doWait(WAITFOR_MSEC); 372 373 CommandReceiver.sendCommand(mContext, 374 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE_LOCATION, 375 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 376 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 377 WatchUidRunner.STATE_CACHED_EMPTY, 378 new Integer(PROCESS_CAPABILITY_NONE)); 379 380 // Put APP1 in TOP state 381 allowBgActivityStart(PACKAGE_NAME_APP1, true); 382 CommandReceiver.sendCommand(mContext, 383 CommandReceiver.COMMAND_START_ACTIVITY, 384 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 385 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 386 WatchUidRunner.STATE_TOP, 387 new Integer(PROCESS_CAPABILITY_ALL)); 388 389 waiter = createBroadcastWaiter(ACTION_START_FGSL_RESULT); 390 // From APP1, start FGSL in APP2. 391 CommandReceiver.sendCommand(mContext, 392 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE_LOCATION, 393 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, bundle); 394 // Now APP2 gets location capability. 395 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 396 WatchUidRunner.STATE_FG_SERVICE, 397 new Integer(PROCESS_CAPABILITY_ALL)); 398 waiter.doWait(WAITFOR_MSEC); 399 400 CommandReceiver.sendCommand(mContext, 401 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE_LOCATION, 402 PACKAGE_NAME_APP2, PACKAGE_NAME_APP2, 0, null); 403 404 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 405 WatchUidRunner.STATE_CACHED_EMPTY, 406 new Integer(PROCESS_CAPABILITY_NONE)); 407 408 CommandReceiver.sendCommand(mContext, 409 CommandReceiver.COMMAND_STOP_ACTIVITY, 410 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 411 412 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 413 WatchUidRunner.STATE_CACHED_EMPTY, 414 new Integer(PROCESS_CAPABILITY_NONE)); 415 } finally { 416 uid1Watcher.finish(); 417 uid2Watcher.finish(); 418 } 419 } 420 421 /** 422 * APP1 is in BG state, by a PendingIntent, it can start FGSL in APP2, 423 * but the FGS won't get location capability. 424 * APP1 is in TOP state, by a PendingIntent, it can start FGSL in APP2, 425 * FGSL gets location capability. 426 * @throws Exception 427 */ 428 @Presubmit 429 @Test testFgsLocationPendingIntent()430 public void testFgsLocationPendingIntent() throws Exception { 431 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 432 PACKAGE_NAME_APP1, 0); 433 ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo( 434 PACKAGE_NAME_APP2, 0); 435 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 436 WAITFOR_MSEC, PROCESS_CAPABILITY_ALL); 437 WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid, 438 WAITFOR_MSEC, PROCESS_CAPABILITY_ALL); 439 440 try { 441 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGSL_RESULT); 442 // APP1 is in BG state, start FGSL in APP2. 443 enableFgsRestriction(false, true, null); 444 CommandReceiver.sendCommand(mContext, 445 CommandReceiver.COMMAND_CREATE_FGSL_PENDING_INTENT, 446 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 447 CommandReceiver.sendCommand(mContext, 448 CommandReceiver.COMMAND_SEND_FGSL_PENDING_INTENT, 449 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 450 // APP2 won't have location capability. 451 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 452 WatchUidRunner.STATE_FG_SERVICE, 453 new Integer(PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK 454 | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK)); 455 waiter.doWait(WAITFOR_MSEC); 456 // Stop FGSL in APP2. 457 CommandReceiver.sendCommand(mContext, 458 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE_LOCATION, 459 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 460 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 461 WatchUidRunner.STATE_CACHED_EMPTY, 462 new Integer(PROCESS_CAPABILITY_NONE)); 463 464 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 465 // Put APP1 in FGS state, start FGSL in APP2. 466 CommandReceiver.sendCommand(mContext, 467 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 468 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 469 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 470 WatchUidRunner.STATE_FG_SERVICE, 471 new Integer(PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK 472 | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK)); 473 waiter.doWait(WAITFOR_MSEC); 474 CommandReceiver.sendCommand(mContext, 475 CommandReceiver.COMMAND_CREATE_FGSL_PENDING_INTENT, 476 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 477 478 waiter = createBroadcastWaiter(ACTION_START_FGSL_RESULT); 479 CommandReceiver.sendCommand(mContext, 480 CommandReceiver.COMMAND_SEND_FGSL_PENDING_INTENT, 481 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 482 // APP2 won't have location capability. 483 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 484 WatchUidRunner.STATE_FG_SERVICE, 485 new Integer(PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK 486 | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK)); 487 waiter.doWait(WAITFOR_MSEC); 488 // stop FGSL in APP2. 489 CommandReceiver.sendCommand(mContext, 490 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE_LOCATION, 491 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 492 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 493 WatchUidRunner.STATE_CACHED_EMPTY, 494 new Integer(PROCESS_CAPABILITY_NONE)); 495 496 // put APP1 in TOP state, start FGSL in APP2. 497 allowBgActivityStart(PACKAGE_NAME_APP1, true); 498 CommandReceiver.sendCommand(mContext, 499 CommandReceiver.COMMAND_START_ACTIVITY, 500 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 501 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 502 WatchUidRunner.STATE_TOP, 503 new Integer(PROCESS_CAPABILITY_ALL)); 504 CommandReceiver.sendCommand(mContext, 505 CommandReceiver.COMMAND_CREATE_FGSL_PENDING_INTENT, 506 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 507 508 waiter = createBroadcastWaiter(ACTION_START_FGSL_RESULT); 509 CommandReceiver.sendCommand(mContext, 510 CommandReceiver.COMMAND_SEND_FGSL_PENDING_INTENT, 511 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 512 // APP2 now have location capability (because APP1 is TOP) 513 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 514 WatchUidRunner.STATE_FG_SERVICE, 515 new Integer(PROCESS_CAPABILITY_ALL)); 516 waiter.doWait(WAITFOR_MSEC); 517 518 // stop FGSL in APP2. 519 CommandReceiver.sendCommand(mContext, 520 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE_LOCATION, 521 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 522 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 523 WatchUidRunner.STATE_CACHED_EMPTY, 524 new Integer(PROCESS_CAPABILITY_NONE)); 525 526 // stop FGS in APP1, 527 CommandReceiver.sendCommand(mContext, 528 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 529 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 530 // stop TOP activity in APP1. 531 CommandReceiver.sendCommand(mContext, 532 CommandReceiver.COMMAND_STOP_ACTIVITY, 533 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 534 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 535 WatchUidRunner.STATE_CACHED_EMPTY, 536 new Integer(PROCESS_CAPABILITY_NONE)); 537 } finally { 538 uid1Watcher.finish(); 539 uid2Watcher.finish(); 540 } 541 } 542 543 /** 544 * Test a FGS start by bind from BG does not get get while-in-use capability. 545 * @throws Exception 546 */ 547 @Presubmit 548 @Test 549 @AsbSecurityTest(cveBugId = 173516292) testFgsLocationStartFromBGWithBind()550 public void testFgsLocationStartFromBGWithBind() throws Exception { 551 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 552 PACKAGE_NAME_APP1, 0); 553 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 554 WAITFOR_MSEC, PROCESS_CAPABILITY_ALL); 555 556 try { 557 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGSL_RESULT); 558 // APP1 is in BG state, bind FGSL in APP1 first. 559 enableFgsRestriction(false, true, null); 560 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_FOREGROUND_SERVICE, 561 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 562 Bundle bundle = new Bundle(); 563 bundle.putInt(LocalForegroundServiceLocation.EXTRA_FOREGROUND_SERVICE_TYPE, 564 ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION 565 | ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA 566 | ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE); 567 // Then start FGSL in APP1, it won't get location capability. 568 CommandReceiver.sendCommand(mContext, 569 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE_LOCATION, 570 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, bundle); 571 572 // APP1 is in FGS state, but won't get location capability. 573 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 574 WatchUidRunner.STATE_FG_SERVICE, 575 new Integer(PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK 576 | PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK)); 577 waiter.doWait(WAITFOR_MSEC); 578 579 // unbind service. 580 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 581 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 582 // stop FGSL 583 CommandReceiver.sendCommand(mContext, 584 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE_LOCATION, 585 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 586 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 587 WatchUidRunner.STATE_CACHED_EMPTY, 588 new Integer(PROCESS_CAPABILITY_NONE)); 589 } finally { 590 uid1Watcher.finish(); 591 } 592 } 593 594 @Presubmit 595 @Test testUpdateUidProcState()596 public void testUpdateUidProcState() throws Exception { 597 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 598 PACKAGE_NAME_APP1, 0); 599 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 600 WAITFOR_MSEC); 601 ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo( 602 PACKAGE_NAME_APP2, 0); 603 WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid, 604 WAITFOR_MSEC); 605 ApplicationInfo app3Info = mContext.getPackageManager().getApplicationInfo( 606 PACKAGE_NAME_APP3, 0); 607 WatchUidRunner uid3Watcher = new WatchUidRunner(mInstrumentation, app3Info.uid, 608 WAITFOR_MSEC); 609 610 try { 611 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 612 613 enableFgsRestriction(false, true, null); 614 615 // START FGS in APP2. 616 CommandReceiver.sendCommand(mContext, 617 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 618 PACKAGE_NAME_APP2, PACKAGE_NAME_APP2, 0, null); 619 // APP2 proc state is 4. 620 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 621 WatchUidRunner.STATE_FG_SERVICE); 622 waiter.doWait(WAITFOR_MSEC); 623 624 // APP2 binds to APP1. 625 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 626 PACKAGE_NAME_APP2, PACKAGE_NAME_APP1, Context.BIND_INCLUDE_CAPABILITIES, null); 627 // APP1 gets proc state 4. 628 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 629 WatchUidRunner.STATE_FG_SERVICE); 630 631 // Start activity in APP3, this put APP3 in TOP state. 632 allowBgActivityStart(PACKAGE_NAME_APP3, true); 633 CommandReceiver.sendCommand(mContext, 634 CommandReceiver.COMMAND_START_ACTIVITY, 635 PACKAGE_NAME_APP3, PACKAGE_NAME_APP3, 0, null); 636 // APP3 gets proc state 2. 637 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP); 638 639 // APP3 repeatedly bind/unbind with APP2, observer APP1 proc state change. 640 // Observe updateUidProcState() call latency. 641 for (int i = 0; i < 10; ++i) { 642 // APP3 bind to APP2 643 CommandReceiver.sendCommand(mContext, 644 CommandReceiver.COMMAND_BIND_SERVICE, 645 PACKAGE_NAME_APP3, PACKAGE_NAME_APP2, Context.BIND_INCLUDE_CAPABILITIES, 646 null); 647 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_BOUND_TOP); 648 649 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 650 PACKAGE_NAME_APP3, PACKAGE_NAME_APP2, 0, null); 651 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 652 } 653 654 // unbind service. 655 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_STOP_ACTIVITY, 656 PACKAGE_NAME_APP3, PACKAGE_NAME_APP3, 0, null); 657 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 658 PACKAGE_NAME_APP3, PACKAGE_NAME_APP2, 0, null); 659 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 660 PACKAGE_NAME_APP2, PACKAGE_NAME_APP1, 0, null); 661 CommandReceiver.sendCommand(mContext, 662 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 663 PACKAGE_NAME_APP2, PACKAGE_NAME_APP2, 0, null); 664 665 } finally { 666 uid1Watcher.finish(); 667 uid2Watcher.finish(); 668 uid3Watcher.finish(); 669 allowBgActivityStart(PACKAGE_NAME_APP3, false); 670 } 671 } 672 673 /** 674 * Test FGS background startForeground() restriction, use DeviceConfig to turn on restriction. 675 * @throws Exception 676 */ 677 @Presubmit 678 @Test testFgsStartFromBG1()679 public void testFgsStartFromBG1() throws Exception { 680 testFgsStartFromBG(true); 681 } 682 683 /** 684 * Test FGS background startForeground() restriction, use AppCompat CHANGE ID to turn on 685 * restriction. 686 * @throws Exception 687 */ 688 @Presubmit 689 @Test testFgsStartFromBG2()690 public void testFgsStartFromBG2() throws Exception { 691 testFgsStartFromBG(false); 692 } 693 testFgsStartFromBG(boolean useDeviceConfig)694 private void testFgsStartFromBG(boolean useDeviceConfig) throws Exception { 695 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 696 PACKAGE_NAME_APP1, 0); 697 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 698 WAITFOR_MSEC); 699 try { 700 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 701 // disable the FGS background startForeground() restriction. 702 enableFgsRestriction(false, true, null); 703 enableFgsRestriction(false, useDeviceConfig, PACKAGE_NAME_APP1); 704 // APP1 is in BG state, Start FGS in APP1. 705 CommandReceiver.sendCommand(mContext, 706 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 707 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 708 // APP1 is in STATE_FG_SERVICE. 709 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 710 waiter.doWait(WAITFOR_MSEC); 711 // stop FGS. 712 CommandReceiver.sendCommand(mContext, 713 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 714 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 715 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 716 717 // Enable the FGS background startForeground() restriction. 718 allowBgActivityStart(PACKAGE_NAME_APP1, false); 719 enableFgsRestriction(true, true, null); 720 enableFgsRestriction(true, useDeviceConfig, PACKAGE_NAME_APP1); 721 // Start FGS in BG state. 722 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 723 CommandReceiver.sendCommand(mContext, 724 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 725 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 726 // APP1 does not enter FGS state 727 try { 728 waiter.doWait(WAITFOR_MSEC); 729 fail("Service should not enter foreground service state"); 730 } catch (Exception e) { 731 } 732 733 // Put APP1 in TOP state. 734 allowBgActivityStart(PACKAGE_NAME_APP1, true); 735 CommandReceiver.sendCommand(mContext, 736 CommandReceiver.COMMAND_START_ACTIVITY, 737 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 738 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP); 739 allowBgActivityStart(PACKAGE_NAME_APP1, false); 740 741 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 742 // Now it can start FGS. 743 CommandReceiver.sendCommand(mContext, 744 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 745 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 746 // Stop activity. 747 CommandReceiver.sendCommand(mContext, 748 CommandReceiver.COMMAND_STOP_ACTIVITY, 749 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 750 // FGS is still running. 751 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 752 waiter.doWait(WAITFOR_MSEC); 753 // Stop the FGS. 754 CommandReceiver.sendCommand(mContext, 755 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 756 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 757 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 758 } finally { 759 uid1Watcher.finish(); 760 } 761 } 762 763 /** 764 * Test a FGS can start from a process that is at BOUND_TOP state. 765 * @throws Exception 766 */ 767 @Presubmit 768 @Test testFgsStartFromBoundTopState()769 public void testFgsStartFromBoundTopState() throws Exception { 770 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 771 PACKAGE_NAME_APP1, 0); 772 ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo( 773 PACKAGE_NAME_APP2, 0); 774 ApplicationInfo app3Info = mContext.getPackageManager().getApplicationInfo( 775 PACKAGE_NAME_APP3, 0); 776 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 777 WAITFOR_MSEC); 778 WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid, 779 WAITFOR_MSEC); 780 WatchUidRunner uid3Watcher = new WatchUidRunner(mInstrumentation, app3Info.uid, 781 WAITFOR_MSEC); 782 try { 783 // Enable the FGS background startForeground() restriction. 784 enableFgsRestriction(true, true, null); 785 786 // Put APP1 in TOP state. 787 allowBgActivityStart(PACKAGE_NAME_APP1, true); 788 CommandReceiver.sendCommand(mContext, 789 CommandReceiver.COMMAND_START_ACTIVITY, 790 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 791 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP); 792 793 // APP1 bound to service in APP2, APP2 get BOUND_TOP state. 794 CommandReceiver.sendCommand(mContext, 795 CommandReceiver.COMMAND_BIND_SERVICE, 796 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 797 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_BOUND_TOP); 798 799 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 800 // APP2 can start FGS in APP3. 801 CommandReceiver.sendCommand(mContext, 802 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 803 PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null); 804 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 805 waiter.doWait(WAITFOR_MSEC); 806 807 // Stop activity. 808 CommandReceiver.sendCommand(mContext, 809 CommandReceiver.COMMAND_STOP_ACTIVITY, 810 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 811 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 812 // unbind service. 813 CommandReceiver.sendCommand(mContext, 814 CommandReceiver.COMMAND_UNBIND_SERVICE, 815 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 816 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 817 // Stop the FGS. 818 CommandReceiver.sendCommand(mContext, 819 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 820 PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null); 821 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 822 } finally { 823 uid1Watcher.finish(); 824 uid2Watcher.finish(); 825 uid3Watcher.finish(); 826 } 827 } 828 829 /** 830 * Test a FGS can start from a process that is at FOREGROUND_SERVICE state. 831 * @throws Exception 832 */ 833 @Presubmit 834 @Test testFgsStartFromFgsState()835 public void testFgsStartFromFgsState() throws Exception { 836 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 837 PACKAGE_NAME_APP1, 0); 838 ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo( 839 PACKAGE_NAME_APP2, 0); 840 ApplicationInfo app3Info = mContext.getPackageManager().getApplicationInfo( 841 PACKAGE_NAME_APP3, 0); 842 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 843 WAITFOR_MSEC); 844 WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid, 845 WAITFOR_MSEC); 846 WatchUidRunner uid3Watcher = new WatchUidRunner(mInstrumentation, app3Info.uid, 847 WAITFOR_MSEC); 848 try { 849 // Enable the FGS background startForeground() restriction. 850 enableFgsRestriction(true, true, null); 851 852 // Put APP1 in TOP state. 853 allowBgActivityStart(PACKAGE_NAME_APP1, true); 854 CommandReceiver.sendCommand(mContext, 855 CommandReceiver.COMMAND_START_ACTIVITY, 856 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 857 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP); 858 859 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 860 // APP1 can start FGS in APP2, APP2 gets FOREGROUND_SERVICE state. 861 CommandReceiver.sendCommand(mContext, 862 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 863 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 864 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 865 waiter.doWait(WAITFOR_MSEC); 866 867 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 868 // APP2 can start FGS in APP3. 869 CommandReceiver.sendCommand(mContext, 870 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 871 PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null); 872 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 873 waiter.doWait(WAITFOR_MSEC); 874 875 // Stop activity in APP1. 876 CommandReceiver.sendCommand(mContext, 877 CommandReceiver.COMMAND_STOP_ACTIVITY, 878 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 879 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 880 // Stop FGS in APP2. 881 CommandReceiver.sendCommand(mContext, 882 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 883 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 884 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 885 // Stop FGS in APP3. 886 CommandReceiver.sendCommand(mContext, 887 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 888 PACKAGE_NAME_APP3, PACKAGE_NAME_APP3, 0, null); 889 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 890 } finally { 891 uid1Watcher.finish(); 892 uid2Watcher.finish(); 893 uid3Watcher.finish(); 894 } 895 } 896 897 /** 898 * When the service is started by bindService() command, test when BG-FGS-launch 899 * restriction is disabled, FGS can start from background. 900 * @throws Exception 901 */ 902 @Presubmit 903 @Test testFgsStartFromBGWithBind()904 public void testFgsStartFromBGWithBind() throws Exception { 905 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 906 PACKAGE_NAME_APP1, 0); 907 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 908 WAITFOR_MSEC); 909 910 try { 911 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGSL_RESULT); 912 // APP1 is in BG state, bind FGSL in APP1 first. 913 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_FOREGROUND_SERVICE, 914 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 915 // Then start FGSL in APP1 916 enableFgsRestriction(false, true, null); 917 CommandReceiver.sendCommand(mContext, 918 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE_LOCATION, 919 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 920 // APP1 is in FGS state 921 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 922 waiter.doWait(WAITFOR_MSEC); 923 924 // stop FGS 925 CommandReceiver.sendCommand(mContext, 926 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE_LOCATION, 927 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 928 // unbind service. 929 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 930 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 931 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 932 } finally { 933 uid1Watcher.finish(); 934 } 935 } 936 937 /** 938 * When the service is started by bindService() command, test when BG-FGS-launch 939 * restriction is enabled, FGS can NOT start from background. 940 * @throws Exception 941 */ 942 @Presubmit 943 @Test testFgsStartFromBGWithBindWithRestriction()944 public void testFgsStartFromBGWithBindWithRestriction() throws Exception { 945 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 946 PACKAGE_NAME_APP1, 0); 947 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 948 WAITFOR_MSEC); 949 950 try { 951 enableFgsRestriction(true, true, null); 952 // APP1 is in BG state, bind FGSL in APP1 first. 953 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_FOREGROUND_SERVICE, 954 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 955 // Then start FGS in APP1 956 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 957 CommandReceiver.sendCommand(mContext, 958 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 959 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 960 // APP1 does not enter FGS state 961 try { 962 waiter.doWait(WAITFOR_MSEC); 963 fail("Service should not enter foreground service state"); 964 } catch (Exception e) { 965 } 966 967 // stop FGS 968 CommandReceiver.sendCommand(mContext, 969 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 970 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 971 // unbind service. 972 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_UNBIND_SERVICE, 973 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 974 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 975 } finally { 976 uid1Watcher.finish(); 977 } 978 } 979 980 /** 981 * Test BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS flag. 982 * Shell has START_ACTIVITIES_FROM_BACKGROUND permission, it can use this bind flag to 983 * pass BG-Activity-launch ability to APP2, then APP2 can start APP2 FGS from background. 984 */ 985 @Presubmit 986 @Test testFgsBindingFlagActivity()987 public void testFgsBindingFlagActivity() throws Exception { 988 testFgsBindingFlag(Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS); 989 } 990 991 /** 992 * Test BIND_ALLOW_FOREGROUND_SERVICE_STARTS_FROM_BACKGROUND flag. 993 * Shell has START_FOREGROUND_SERVICES_FROM_BACKGROUND permission, it can use this bind flag to 994 * pass BG-FGS-launch ability to APP2, then APP2 can start APP3 FGS from background. 995 */ 996 @Presubmit 997 @Test testFgsBindingFlagFGS()998 public void testFgsBindingFlagFGS() throws Exception { 999 testFgsBindingFlag(Context.BIND_ALLOW_FOREGROUND_SERVICE_STARTS_FROM_BACKGROUND); 1000 } 1001 1002 /** 1003 * Test no binding flag. 1004 * Shell has START_FOREGROUND_SERVICES_FROM_BACKGROUND permission, without any bind flag, 1005 * the BG-FGS-launch ability can be passed to APP2 by service binding, then APP2 can start 1006 * APP3 FGS from background. 1007 */ 1008 @Presubmit 1009 @Test testFgsBindingFlagNone()1010 public void testFgsBindingFlagNone() throws Exception { 1011 testFgsBindingFlag(0); 1012 } 1013 testFgsBindingFlag(int bindingFlag)1014 private void testFgsBindingFlag(int bindingFlag) throws Exception { 1015 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 1016 PACKAGE_NAME_APP1, 0); 1017 ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo( 1018 PACKAGE_NAME_APP2, 0); 1019 ApplicationInfo app3Info = mContext.getPackageManager().getApplicationInfo( 1020 PACKAGE_NAME_APP3, 0); 1021 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 1022 WAITFOR_MSEC); 1023 WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid, 1024 WAITFOR_MSEC); 1025 WatchUidRunner uid3Watcher = new WatchUidRunner(mInstrumentation, app3Info.uid, 1026 WAITFOR_MSEC); 1027 try { 1028 // Enable the FGS background startForeground() restriction. 1029 enableFgsRestriction(true, true, null); 1030 1031 // testapp is in background. 1032 // testapp binds to service in APP2, APP2 still in background state. 1033 final Intent intent = new Intent().setClassName( 1034 PACKAGE_NAME_APP2, "android.app.stubs.LocalService"); 1035 1036 /* 1037 final ServiceConnection connection = new ServiceConnection() { 1038 @Override 1039 public void onServiceConnected(ComponentName name, IBinder service) { 1040 } 1041 @Override 1042 public void onServiceDisconnected(ComponentName name) { 1043 } 1044 }; 1045 runWithShellPermissionIdentity(() -> { 1046 mTargetContext.bindService(intent, connection, 1047 Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY); 1048 }); 1049 1050 // APP2 can not start FGS in APP3. 1051 WaitForBroadcast waiter = new WaitForBroadcast(mInstrumentation.getTargetContext()); 1052 waiter.prepare(ACTION_START_FGS_RESULT); 1053 CommandReceiver.sendCommand(mContext, 1054 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1055 PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null); 1056 try { 1057 waiter.doWait(WAITFOR_MSEC); 1058 fail("Service should not enter foreground service state"); 1059 } catch (Exception e) { 1060 } 1061 1062 // testapp unbind service in APP2. 1063 runWithShellPermissionIdentity(() -> mTargetContext.unbindService(connection)); 1064 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1065 */ 1066 1067 // testapp is in background. 1068 // testapp binds to service in APP2 using the binding flag. 1069 // APP2 still in background state. 1070 final ServiceConnection connection2 = new ServiceConnection() { 1071 @Override 1072 public void onServiceConnected(ComponentName name, IBinder service) { 1073 } 1074 @Override 1075 public void onServiceDisconnected(ComponentName name) { 1076 } 1077 }; 1078 runWithShellPermissionIdentity(() -> mTargetContext.bindService(intent, connection2, 1079 Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY 1080 | bindingFlag)); 1081 1082 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1083 // Because the binding flag, 1084 // APP2 can start FGS from background. 1085 CommandReceiver.sendCommand(mContext, 1086 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1087 PACKAGE_NAME_APP2, PACKAGE_NAME_APP3, 0, null); 1088 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1089 waiter.doWait(WAITFOR_MSEC); 1090 1091 // testapp unbind service in APP2. 1092 runWithShellPermissionIdentity(() -> mTargetContext.unbindService(connection2)); 1093 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1094 // Stop the FGS in APP3. 1095 CommandReceiver.sendCommand(mContext, 1096 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 1097 PACKAGE_NAME_APP3, PACKAGE_NAME_APP3, 0, null); 1098 uid3Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1099 } finally { 1100 uid1Watcher.finish(); 1101 uid2Watcher.finish(); 1102 uid3Watcher.finish(); 1103 } 1104 } 1105 1106 /** 1107 * Test a FGS can start from BG if the app has SYSTEM_ALERT_WINDOW permission. 1108 */ 1109 @Presubmit 1110 @Test 1111 @RequiresFlagsDisabled(Flags.FLAG_FGS_DISABLE_SAW) testFgsStartSystemAlertWindow()1112 public void testFgsStartSystemAlertWindow() throws Exception { 1113 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 1114 PACKAGE_NAME_APP1, 0); 1115 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 1116 WAITFOR_MSEC); 1117 try { 1118 // Enable the FGS background startForeground() restriction. 1119 enableFgsRestriction(true, true, null); 1120 for (String packageName : PACKAGE_NAMES) { 1121 enableFgsSawRestriction(false, packageName); 1122 } 1123 // Start FGS in BG state. 1124 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1125 CommandReceiver.sendCommand(mContext, 1126 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1127 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1128 // APP1 does not enter FGS state 1129 try { 1130 waiter.doWait(WAITFOR_MSEC); 1131 fail("Service should not enter foreground service state"); 1132 } catch (Exception e) { 1133 } 1134 1135 PermissionUtils.grantPermission( 1136 PACKAGE_NAME_APP1, android.Manifest.permission.SYSTEM_ALERT_WINDOW); 1137 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1138 // Now it can start FGS. 1139 CommandReceiver.sendCommand(mContext, 1140 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1141 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1142 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1143 waiter.doWait(WAITFOR_MSEC); 1144 // Stop the FGS. 1145 CommandReceiver.sendCommand(mContext, 1146 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 1147 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1148 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1149 } finally { 1150 uid1Watcher.finish(); 1151 } 1152 } 1153 1154 @Test 1155 @RequiresFlagsEnabled(Flags.FLAG_FGS_DISABLE_SAW) testFgsStartSystemAlertWindowDisabled()1156 public void testFgsStartSystemAlertWindowDisabled() throws Exception { 1157 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 1158 PACKAGE_NAME_APP1, 0); 1159 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 1160 WAITFOR_MSEC); 1161 try { 1162 // Enable the FGS background startForeground() restriction. 1163 enableFgsRestriction(true, true, null); 1164 for (String packageName : PACKAGE_NAMES) { 1165 enableFgsSawRestriction(true, packageName); 1166 } 1167 // Start FGS in BG state. 1168 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1169 CommandReceiver.sendCommand(mContext, 1170 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1171 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1172 // APP1 does not enter FGS state 1173 try { 1174 waiter.doWait(WAITFOR_MSEC); 1175 fail("Service should not enter foreground service state"); 1176 } catch (Exception e) { 1177 } 1178 1179 PermissionUtils.grantPermission( 1180 PACKAGE_NAME_APP1, android.Manifest.permission.SYSTEM_ALERT_WINDOW); 1181 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1182 // It should still fail 1183 CommandReceiver.sendCommand(mContext, 1184 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1185 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1186 // STOPSHIP(b/296558535): Update to test with a system alert overlay 1187 try { 1188 waiter.doWait(WAITFOR_MSEC); 1189 fail("Service should not enter foreground service state"); 1190 } catch (Exception e) { 1191 } 1192 } finally { 1193 uid1Watcher.finish(); 1194 } 1195 } 1196 1197 /** 1198 * Test a FGS can start from BG if the device is in retail demo mode. 1199 */ 1200 @Presubmit 1201 @Test 1202 // Change Settings.Global.DEVICE_DEMO_MODE on device may trigger other listener and put 1203 // the device in undesired state, for example, the battery charge level is set to 35% 1204 // permanently, ignore this test for now. 1205 @Ignore testFgsStartRetailDemoMode()1206 public void testFgsStartRetailDemoMode() throws Exception { 1207 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 1208 PACKAGE_NAME_APP1, 0); 1209 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 1210 WAITFOR_MSEC); 1211 runWithShellPermissionIdentity(()-> { 1212 mOrigDeviceDemoMode = Settings.Global.getInt(mContext.getContentResolver(), 1213 Settings.Global.DEVICE_DEMO_MODE, 0); }); 1214 1215 try { 1216 // Enable the FGS background startForeground() restriction. 1217 enableFgsRestriction(true, true, null); 1218 // Start FGS in BG state. 1219 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1220 CommandReceiver.sendCommand(mContext, 1221 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1222 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1223 // APP1 does not enter FGS state 1224 try { 1225 waiter.doWait(WAITFOR_MSEC); 1226 fail("Service should not enter foreground service state"); 1227 } catch (Exception e) { 1228 } 1229 1230 runWithShellPermissionIdentity(()-> { 1231 Settings.Global.putInt(mContext.getContentResolver(), 1232 Settings.Global.DEVICE_DEMO_MODE, 1); }); 1233 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1234 // Now it can start FGS. 1235 CommandReceiver.sendCommand(mContext, 1236 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1237 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1238 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1239 waiter.doWait(WAITFOR_MSEC); 1240 // Stop the FGS. 1241 CommandReceiver.sendCommand(mContext, 1242 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 1243 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1244 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1245 } finally { 1246 uid1Watcher.finish(); 1247 runWithShellPermissionIdentity(()-> { 1248 Settings.Global.putInt(mContext.getContentResolver(), 1249 Settings.Global.DEVICE_DEMO_MODE, mOrigDeviceDemoMode); }); 1250 } 1251 } 1252 1253 // At Context.startForegroundService() or Service.startForeground() calls, if the FGS is 1254 // restricted by background restriction and the app's targetSdkVersion is at least S, the 1255 // framework throws a ForegroundServiceStartNotAllowedException with error message. 1256 @Test 1257 @Ignore("The instrumentation is allowed to star FGS, it does not throw the exception") testFgsStartFromBGException()1258 public void testFgsStartFromBGException() throws Exception { 1259 ForegroundServiceStartNotAllowedException expectedException = null; 1260 final Intent intent = new Intent().setClassName( 1261 PACKAGE_NAME_APP1, "android.app.stubs.LocalForegroundService"); 1262 try { 1263 allowBgActivityStart("android.app.stubs", false); 1264 enableFgsRestriction(true, true, null); 1265 mContext.startForegroundService(intent); 1266 } catch (ForegroundServiceStartNotAllowedException e) { 1267 expectedException = e; 1268 } finally { 1269 mContext.stopService(intent); 1270 allowBgActivityStart("android.app.stubs", true); 1271 } 1272 String expectedMessage = "mAllowStartForeground false"; 1273 assertNotNull(expectedException); 1274 assertTrue(expectedException.getMessage().contains(expectedMessage)); 1275 } 1276 1277 /** 1278 * Test a FGS can start from BG if the app is in the DeviceIdleController's AllowList. 1279 */ 1280 @Presubmit 1281 @Test testFgsStartAllowList()1282 public void testFgsStartAllowList() throws Exception { 1283 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 1284 PACKAGE_NAME_APP1, 0); 1285 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 1286 WAITFOR_MSEC); 1287 try { 1288 // Enable the FGS background startForeground() restriction. 1289 enableFgsRestriction(true, true, null); 1290 // Start FGS in BG state. 1291 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1292 CommandReceiver.sendCommand(mContext, 1293 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1294 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1295 // APP1 does not enter FGS state 1296 try { 1297 waiter.doWait(WAITFOR_MSEC); 1298 fail("Service should not enter foreground service state"); 1299 } catch (Exception e) { 1300 } 1301 1302 // Add package to AllowList. 1303 CtsAppTestUtils.executeShellCmd(mInstrumentation, 1304 "dumpsys deviceidle whitelist +" + PACKAGE_NAME_APP1); 1305 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1306 // Now it can start FGS. 1307 CommandReceiver.sendCommand(mContext, 1308 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1309 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1310 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1311 waiter.doWait(WAITFOR_MSEC); 1312 // Stop the FGS. 1313 CommandReceiver.sendCommand(mContext, 1314 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 1315 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1316 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1317 } finally { 1318 uid1Watcher.finish(); 1319 // Remove package from AllowList. 1320 CtsAppTestUtils.executeShellCmd(mInstrumentation, 1321 "dumpsys deviceidle whitelist -" + PACKAGE_NAME_APP1); 1322 } 1323 } 1324 1325 /** 1326 * Test temp allowlist types in BroadcastOptions. 1327 */ 1328 @Presubmit 1329 @Test testTempAllowListType()1330 public void testTempAllowListType() throws Exception { 1331 testTempAllowListTypeInternal(TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED); 1332 testTempAllowListTypeInternal(TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED); 1333 } 1334 testTempAllowListTypeInternal(int type)1335 private void testTempAllowListTypeInternal(int type) throws Exception { 1336 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 1337 PACKAGE_NAME_APP1, 0); 1338 ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo( 1339 PACKAGE_NAME_APP2, 0); 1340 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 1341 WAITFOR_MSEC); 1342 WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid, 1343 WAITFOR_MSEC); 1344 try { 1345 // Enable the FGS background startForeground() restriction. 1346 enableFgsRestriction(true, true, null); 1347 // Start FGS in BG state. 1348 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1349 CommandReceiver.sendCommand(mContext, 1350 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1351 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 1352 // APP1 does not enter FGS state 1353 try { 1354 waiter.doWait(WAITFOR_MSEC); 1355 fail("Service should not enter foreground service state"); 1356 } catch (Exception e) { 1357 } 1358 1359 // Now it can start FGS. 1360 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1361 runWithShellPermissionIdentity(()-> { 1362 final BroadcastOptions options = BroadcastOptions.makeBasic(); 1363 // setTemporaryAppAllowlist API requires 1364 // START_FOREGROUND_SERVICES_FROM_BACKGROUND permission. 1365 options.setTemporaryAppAllowlist(TEMP_ALLOWLIST_DURATION_MS, type, REASON_UNKNOWN, 1366 ""); 1367 // Must use Shell to issue this command because Shell has 1368 // START_FOREGROUND_SERVICES_FROM_BACKGROUND permission. 1369 CommandReceiver.sendCommandWithBroadcastOptions(mContext, 1370 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1371 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null, 1372 options); 1373 }); 1374 if (type == TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED) { 1375 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1376 waiter.doWait(WAITFOR_MSEC); 1377 // Stop the FGS. 1378 CommandReceiver.sendCommand(mContext, 1379 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 1380 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 1381 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 1382 WatchUidRunner.STATE_CACHED_EMPTY); 1383 } else if (type == TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED) { 1384 // APP1 does not enter FGS state 1385 try { 1386 waiter.doWait(WAITFOR_MSEC); 1387 fail("Service should not enter foreground service state"); 1388 } catch (Exception e) { 1389 } 1390 } 1391 } finally { 1392 uid1Watcher.finish(); 1393 uid2Watcher.finish(); 1394 // Sleep 10 seconds to let the temp allowlist expire so it won't affect next test case. 1395 SystemClock.sleep(TEMP_ALLOWLIST_DURATION_MS); 1396 } 1397 1398 } 1399 1400 /** 1401 * Test a FGS can start from BG if the process had a visible activity recently. 1402 */ 1403 @LargeTest 1404 @Test testVisibleActivityGracePeriod()1405 public void testVisibleActivityGracePeriod() throws Exception { 1406 ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo( 1407 PACKAGE_NAME_APP2, 0); 1408 WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid, 1409 WAITFOR_MSEC); 1410 final String namespaceActivityManager = "activity_manager"; 1411 final String keyFgToBgFgsGraceDuration = "fg_to_bg_fgs_grace_duration"; 1412 final long[] curFgToBgFgsGraceDuration = {-1}; 1413 try { 1414 // Enable the FGS background startForeground() restriction. 1415 enableFgsRestriction(true, true, null); 1416 // Allow bg actvity start from APP1. 1417 allowBgActivityStart(PACKAGE_NAME_APP1, true); 1418 1419 SystemUtil.runWithShellPermissionIdentity(() -> { 1420 curFgToBgFgsGraceDuration[0] = DeviceConfig.getInt( 1421 namespaceActivityManager, 1422 keyFgToBgFgsGraceDuration, -1); 1423 DeviceConfig.setProperty(namespaceActivityManager, 1424 keyFgToBgFgsGraceDuration, 1425 Long.toString(WAITFOR_MSEC), false); 1426 }); 1427 1428 testVisibleActivityGracePeriodInternal(uid2Watcher, "KEYCODE_HOME"); 1429 testVisibleActivityGracePeriodInternal(uid2Watcher, "KEYCODE_BACK"); 1430 } finally { 1431 uid2Watcher.finish(); 1432 // Remove package from AllowList. 1433 allowBgActivityStart(PACKAGE_NAME_APP1, false); 1434 if (curFgToBgFgsGraceDuration[0] >= 0) { 1435 SystemUtil.runWithShellPermissionIdentity(() -> { 1436 DeviceConfig.setProperty(namespaceActivityManager, 1437 keyFgToBgFgsGraceDuration, 1438 Long.toString(curFgToBgFgsGraceDuration[0]), false); 1439 }); 1440 } else { 1441 CtsAppTestUtils.executeShellCmd(mInstrumentation, 1442 "device_config delete " + namespaceActivityManager 1443 + " " + keyFgToBgFgsGraceDuration); 1444 } 1445 } 1446 } 1447 testVisibleActivityGracePeriodInternal(WatchUidRunner uidWatcher, String keyCode)1448 private void testVisibleActivityGracePeriodInternal(WatchUidRunner uidWatcher, String keyCode) 1449 throws Exception { 1450 testVisibleActivityGracePeriodInternal(uidWatcher, keyCode, null, 1451 () -> uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 1452 WatchUidRunner.STATE_FG_SERVICE), true); 1453 1454 testVisibleActivityGracePeriodInternal(uidWatcher, keyCode, 1455 () -> SystemClock.sleep(WAITFOR_MSEC + 2000), // Wait for the grace period to expire 1456 () -> { 1457 try { 1458 uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 1459 WatchUidRunner.STATE_FG_SERVICE); 1460 fail("Service should not enter foreground service state"); 1461 } catch (Exception e) { 1462 // Expected. 1463 } 1464 }, false); 1465 } 1466 testVisibleActivityGracePeriodInternal(WatchUidRunner uidWatcher, String keyCode, Runnable prep, Runnable verifier, boolean stopFgs)1467 private void testVisibleActivityGracePeriodInternal(WatchUidRunner uidWatcher, 1468 String keyCode, Runnable prep, Runnable verifier, boolean stopFgs) throws Exception { 1469 // Put APP2 in TOP state. 1470 CommandReceiver.sendCommand(mContext, 1471 CommandReceiver.COMMAND_START_ACTIVITY, 1472 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 1473 uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP); 1474 1475 // Take a nap to wait for the UI to settle down. 1476 SystemClock.sleep(2000); 1477 1478 // Now inject key event. 1479 CtsAppTestUtils.executeShellCmd(mInstrumentation, "input -d " 1480 + mUserHelper.getMainDisplayId() + " keyevent " + keyCode); 1481 1482 // It should go to the cached state. 1483 uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null); 1484 1485 if (prep != null) { 1486 prep.run(); 1487 } 1488 1489 // Start FGS from APP2. 1490 CommandReceiver.sendCommand(mContext, 1491 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1492 PACKAGE_NAME_APP2, PACKAGE_NAME_APP2, 0, null); 1493 1494 if (verifier != null) { 1495 verifier.run(); 1496 } 1497 1498 if (stopFgs) { 1499 // Stop the FGS. 1500 CommandReceiver.sendCommand(mContext, 1501 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 1502 PACKAGE_NAME_APP2, PACKAGE_NAME_APP2, 0, null); 1503 uidWatcher.waitFor(WatchUidRunner.CMD_CACHED, null); 1504 } 1505 } 1506 1507 /** 1508 * After background service is started, after 10 seconds timeout, the startForeground() can 1509 * succeed or not depends on the service's app proc state. 1510 * Test starService() -> startForeground() 1511 */ 1512 @Presubmit 1513 @Test testStartForegroundTimeout()1514 public void testStartForegroundTimeout() throws Exception { 1515 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 1516 PACKAGE_NAME_APP1, 0); 1517 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 1518 WAITFOR_MSEC, PROCESS_CAPABILITY_ALL); 1519 try { 1520 // Enable the FGS background startForeground() restriction. 1521 enableFgsRestriction(true, true, null); 1522 setFgsStartForegroundTimeout(DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS); 1523 1524 // Put app to a TOP proc state. 1525 allowBgActivityStart(PACKAGE_NAME_APP1, true); 1526 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_START_ACTIVITY, 1527 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1528 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP); 1529 allowBgActivityStart(PACKAGE_NAME_APP1, false); 1530 1531 // start background service. 1532 Bundle extras = LocalForegroundService.newCommand( 1533 LocalForegroundService.COMMAND_START_NO_FOREGROUND); 1534 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_START_SERVICE, 1535 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, extras); 1536 1537 // stop the activity. 1538 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_STOP_ACTIVITY, 1539 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1540 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE); 1541 1542 // Sleep after the timeout DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS 1543 SystemClock.sleep(DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS + 1000); 1544 1545 extras = LocalForegroundService.newCommand( 1546 LocalForegroundService.COMMAND_START_FOREGROUND); 1547 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_START_SERVICE, 1548 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, extras); 1549 // APP1 does not enter FGS state 1550 // startForeground() is called after 10 seconds FgsStartForegroundTimeout. 1551 try { 1552 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1553 fail("Service should not enter foreground service state"); 1554 } catch (Exception e) { 1555 } 1556 1557 // Put app to a TOP proc state. 1558 allowBgActivityStart(PACKAGE_NAME_APP1, true); 1559 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_START_ACTIVITY, 1560 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1561 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 1562 WatchUidRunner.STATE_TOP, new Integer(PROCESS_CAPABILITY_ALL)); 1563 allowBgActivityStart(PACKAGE_NAME_APP1, false); 1564 1565 // Call startForeground(). 1566 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1567 extras = LocalForegroundService.newCommand( 1568 LocalForegroundService.COMMAND_START_FOREGROUND); 1569 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_START_SERVICE, 1570 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, extras); 1571 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_STOP_ACTIVITY, 1572 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1573 1574 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1575 waiter.doWait(WAITFOR_MSEC); 1576 1577 // Stop the FGS. 1578 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_STOP_SERVICE, 1579 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1580 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY, 1581 new Integer(PROCESS_CAPABILITY_NONE)); 1582 } finally { 1583 uid1Watcher.finish(); 1584 setFgsStartForegroundTimeout(DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS); 1585 } 1586 } 1587 1588 /** 1589 * After startForeground() and stopForeground(), the second startForeground() can succeed or not 1590 * depends on the service's app proc state. 1591 * Test startForegroundService() -> startForeground() -> stopForeground() -> startForeground() 1592 * -> startForeground(). 1593 */ 1594 @Presubmit 1595 @Test testSecondStartForeground()1596 public void testSecondStartForeground() throws Exception { 1597 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 1598 PACKAGE_NAME_APP1, 0); 1599 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 1600 WAITFOR_MSEC, PROCESS_CAPABILITY_ALL); 1601 try { 1602 // Enable the FGS background startForeground() restriction. 1603 enableFgsRestriction(true, true, null); 1604 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1605 // Bypass bg-service-start restriction. 1606 CtsAppTestUtils.executeShellCmd(mInstrumentation, 1607 "dumpsys deviceidle whitelist +" + PACKAGE_NAME_APP1); 1608 // Start foreground service from APP1, the service can enter FGS. 1609 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1610 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1611 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1612 waiter.doWait(WAITFOR_MSEC); 1613 CtsAppTestUtils.executeShellCmd(mInstrumentation, 1614 "dumpsys deviceidle whitelist -" + PACKAGE_NAME_APP1); 1615 1616 // stopForeground(), the service exits FGS, become a background service. 1617 Bundle extras = LocalForegroundService.newCommand( 1618 LocalForegroundService.COMMAND_STOP_FOREGROUND_REMOVE_NOTIFICATION); 1619 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_START_SERVICE, 1620 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, extras); 1621 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE, 1622 new Integer(PROCESS_CAPABILITY_NONE)); 1623 1624 // APP2 is in the background, from APP2, call startForeground(). 1625 // When APP2 calls Context.startService(), setFgsRestrictionLocked() is called, 1626 // because APP2 is in the background, mAllowStartForeground is set to false. 1627 // When Service.startForeground() is called, setFgsRestrictionLocked() is called again, 1628 // APP1's proc state is in the background and mAllowStartForeground is set to false. 1629 extras = LocalForegroundService.newCommand( 1630 LocalForegroundService.COMMAND_START_FOREGROUND); 1631 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_START_SERVICE, 1632 PACKAGE_NAME_APP2, PACKAGE_NAME_APP1, 0, extras); 1633 try { 1634 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1635 fail("Service should not enter foreground service state"); 1636 } catch (Exception e) { 1637 } 1638 1639 // Put APP1 to a TOP proc state. 1640 allowBgActivityStart(PACKAGE_NAME_APP1, true); 1641 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_START_ACTIVITY, 1642 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1643 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_TOP, 1644 new Integer(PROCESS_CAPABILITY_ALL)); 1645 allowBgActivityStart(PACKAGE_NAME_APP1, false); 1646 1647 // APP2 is in the background, from APP2, call startForeground() second time. 1648 // When APP2 calls Context.startService(), setFgsRestrictionLocked() is called, 1649 // because APP2 is in the background, mAllowStartForeground is set to false. 1650 // When Service.startForeground() is called, setFgsRestrictionLocked() is called again, 1651 // because APP1's proc state is in the foreground and mAllowStartForeground is set to 1652 // true. 1653 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1654 extras = LocalForegroundService.newCommand( 1655 LocalForegroundService.COMMAND_START_FOREGROUND); 1656 extras.putInt(LocalForegroundServiceLocation.EXTRA_FOREGROUND_SERVICE_TYPE, 1657 ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA 1658 | ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE); 1659 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_START_SERVICE, 1660 PACKAGE_NAME_APP2, PACKAGE_NAME_APP1, 0, extras); 1661 waiter.doWait(WAITFOR_MSEC); 1662 // Stop app1's activity. 1663 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_STOP_ACTIVITY, 1664 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1665 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE, 1666 LOCAL_SERVICE_PROCESS_CAPABILITY); 1667 1668 // Stop the FGS. 1669 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 1670 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1671 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY, 1672 new Integer(PROCESS_CAPABILITY_NONE)); 1673 } finally { 1674 uid1Watcher.finish(); 1675 } 1676 } 1677 1678 /** 1679 * Test OP_ACTIVATE_VPN and OP_ACTIVATE_PLATFORM_VPN are exempted from BG-FGS-launch 1680 * restriction. 1681 * @throws Exception 1682 */ 1683 @Presubmit 1684 @Test testFgsStartVpn()1685 public void testFgsStartVpn() throws Exception { 1686 testFgsStartVpnInternal("ACTIVATE_VPN"); 1687 testFgsStartVpnInternal("ACTIVATE_PLATFORM_VPN"); 1688 } 1689 testFgsStartVpnInternal(String vpnAppOp)1690 private void testFgsStartVpnInternal(String vpnAppOp) throws Exception { 1691 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 1692 PACKAGE_NAME_APP1, 0); 1693 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 1694 WAITFOR_MSEC); 1695 try { 1696 // Enable the FGS background startForeground() restriction. 1697 enableFgsRestriction(true, true, null); 1698 // Start FGS in BG state. 1699 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1700 CommandReceiver.sendCommand(mContext, 1701 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1702 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1703 // APP1 does not enter FGS state 1704 try { 1705 waiter.doWait(WAITFOR_MSEC); 1706 fail("Service should not enter foreground service state"); 1707 } catch (Exception e) { 1708 } 1709 1710 setAppOp(PACKAGE_NAME_APP1, vpnAppOp, true); 1711 1712 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1713 // Now it can start FGS. 1714 CommandReceiver.sendCommand(mContext, 1715 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1716 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1717 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1718 waiter.doWait(WAITFOR_MSEC); 1719 // Stop the FGS. 1720 CommandReceiver.sendCommand(mContext, 1721 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 1722 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1723 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1724 } finally { 1725 uid1Watcher.finish(); 1726 CtsAppTestUtils.executeShellCmd(mInstrumentation, 1727 "appops reset --user " + mTestRunningUserId + " " + PACKAGE_NAME_APP1); 1728 } 1729 } 1730 1731 /** 1732 * The default behavior for temp allowlist reasonCode REASON_PUSH_MESSAGING_OVER_QUOTA 1733 * is TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED (not allowed to start FGS). But 1734 * the behavior can be changed by device config command. There are three possible values: 1735 * {@link TEMPORARY_ALLOW_LIST_TYPE_NONE} (-1): 1736 * not temp allowlisted. 1737 * {@link TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED} (0): 1738 * temp allowlisted and allow FGS. 1739 * {@link TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED} (1): 1740 * temp allowlisted, not allow FGS. 1741 */ 1742 @Presubmit 1743 @Test testPushMessagingOverQuota()1744 public void testPushMessagingOverQuota() throws Exception { 1745 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 1746 PACKAGE_NAME_APP1, 0); 1747 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 1748 WAITFOR_MSEC); 1749 final int defaultBehavior = getPushMessagingOverQuotaBehavior(); 1750 try { 1751 // Enable the FGS background startForeground() restriction. 1752 enableFgsRestriction(true, true, null); 1753 // Default behavior is TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED. 1754 setPushMessagingOverQuotaBehavior( 1755 TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED); 1756 // Start FGS in BG state. 1757 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1758 CommandReceiver.sendCommand(mContext, 1759 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1760 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1761 // APP1 does not enter FGS state 1762 try { 1763 waiter.doWait(WAITFOR_MSEC); 1764 fail("Service should not enter foreground service state"); 1765 } catch (Exception e) { 1766 } 1767 1768 setPushMessagingOverQuotaBehavior(TEMPORARY_ALLOW_LIST_TYPE_NONE); 1769 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1770 runWithShellPermissionIdentity(() -> { 1771 mContext.getSystemService(PowerExemptionManager.class).addToTemporaryAllowList( 1772 PACKAGE_NAME_APP1, PowerExemptionManager.REASON_PUSH_MESSAGING_OVER_QUOTA, 1773 "", TEMP_ALLOWLIST_DURATION_MS); 1774 }); 1775 CommandReceiver.sendCommand(mContext, 1776 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1777 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1778 // APP1 does not enter FGS state 1779 try { 1780 waiter.doWait(WAITFOR_MSEC); 1781 fail("Service should not enter foreground service state"); 1782 } catch (Exception e) { 1783 } 1784 1785 // Change behavior to TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED. 1786 setPushMessagingOverQuotaBehavior( 1787 TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED); 1788 runWithShellPermissionIdentity(() -> { 1789 mContext.getSystemService(PowerExemptionManager.class).addToTemporaryAllowList( 1790 PACKAGE_NAME_APP1, PowerExemptionManager.REASON_PUSH_MESSAGING_OVER_QUOTA, 1791 "", TEMP_ALLOWLIST_DURATION_MS); 1792 }); 1793 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1794 // Now it can start FGS. 1795 CommandReceiver.sendCommand(mContext, 1796 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1797 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1798 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1799 waiter.doWait(WAITFOR_MSEC); 1800 // Stop the FGS. 1801 CommandReceiver.sendCommand(mContext, 1802 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 1803 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1804 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 1805 } finally { 1806 uid1Watcher.finish(); 1807 // Change back to default behavior. 1808 setPushMessagingOverQuotaBehavior(defaultBehavior); 1809 // allow temp allowlist to expire. 1810 SystemClock.sleep(TEMP_ALLOWLIST_DURATION_MS); 1811 } 1812 } 1813 1814 /** 1815 * Test temp allowlist reasonCode in BroadcastOptions. 1816 * When REASON_PUSH_MESSAGING_OVER_QUOTA, DeviceIdleController changes temp allowlist type to 1817 * TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED so FGS start is not allowed. 1818 * When REASON_DENIED (-1), DeviceIdleController changes temp allowlist type to 1819 * TEMPORARY_ALLOWLIST_TYPE_NONE, the temp allowlist itself is not allowed. 1820 * All other reason codes, DeviceIdleController does not change temp allowlist type. 1821 */ 1822 @Presubmit 1823 @Test testTempAllowListReasonCode()1824 public void testTempAllowListReasonCode() throws Exception { 1825 // FGS start is temp allowed. 1826 testTempAllowListReasonCodeInternal(REASON_PUSH_MESSAGING); 1827 // FGS start is not allowed. 1828 testTempAllowListReasonCodeInternal(REASON_PUSH_MESSAGING_OVER_QUOTA); 1829 // Temp allowlist itself is not allowed. REASON_DENIED is not exposed in 1830 // PowerExemptionManager, just use its value "-1" here. 1831 testTempAllowListReasonCodeInternal(-1); 1832 } 1833 testTempAllowListReasonCodeInternal(int reasonCode)1834 private void testTempAllowListReasonCodeInternal(int reasonCode) throws Exception { 1835 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 1836 PACKAGE_NAME_APP1, 0); 1837 ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo( 1838 PACKAGE_NAME_APP2, 0); 1839 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 1840 WAITFOR_MSEC); 1841 WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid, 1842 WAITFOR_MSEC); 1843 final int defaultBehavior = getPushMessagingOverQuotaBehavior(); 1844 try { 1845 setPushMessagingOverQuotaBehavior( 1846 TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED); 1847 // Enable the FGS background startForeground() restriction. 1848 enableFgsRestriction(true, true, null); 1849 // Now it can start FGS. 1850 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1851 runWithShellPermissionIdentity(() -> { 1852 final BroadcastOptions options = BroadcastOptions.makeBasic(); 1853 // setTemporaryAppAllowlist API requires 1854 // START_FOREGROUND_SERVICES_FROM_BACKGROUND permission. 1855 options.setTemporaryAppAllowlist(TEMP_ALLOWLIST_DURATION_MS, 1856 TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED, reasonCode, 1857 ""); 1858 // Must use Shell to issue this command because Shell has 1859 // START_FOREGROUND_SERVICES_FROM_BACKGROUND permission. 1860 CommandReceiver.sendCommandWithBroadcastOptions(mContext, 1861 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1862 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null, 1863 options); 1864 }); 1865 if (reasonCode == REASON_PUSH_MESSAGING) { 1866 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1867 waiter.doWait(WAITFOR_MSEC); 1868 // Stop the FGS. 1869 CommandReceiver.sendCommand(mContext, 1870 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 1871 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 1872 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 1873 WatchUidRunner.STATE_CACHED_EMPTY); 1874 } else if (reasonCode == REASON_PUSH_MESSAGING_OVER_QUOTA) { 1875 // APP1 does not enter FGS state 1876 try { 1877 waiter.doWait(WAITFOR_MSEC); 1878 fail("Service should not enter foreground service state"); 1879 } catch (Exception e) { 1880 } 1881 } 1882 } finally { 1883 uid1Watcher.finish(); 1884 uid2Watcher.finish(); 1885 setPushMessagingOverQuotaBehavior(defaultBehavior); 1886 // Sleep to let the temp allowlist expire so it won't affect next test case. 1887 SystemClock.sleep(TEMP_ALLOWLIST_DURATION_MS); 1888 } 1889 } 1890 1891 /** 1892 * AlarmManagerService uses REASON_ALARM_MANAGER_ALARM_CLOCK(301) to temp allow FGS start. 1893 * Test when temp allowlist reasonCode is REASON_ALARM_MANAGER_ALARM_CLOCK, even the app is 1894 * background-restricted (appop RUN_ANY_IN_BACKGROUND is false), the app can still start FGS. 1895 */ 1896 @Presubmit 1897 @Test testTempAllowListReasonCodeAlarmClock()1898 public void testTempAllowListReasonCodeAlarmClock() throws Exception { 1899 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 1900 PACKAGE_NAME_APP1, 0); 1901 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 1902 WAITFOR_MSEC); 1903 final String dumpCommand = "dumpsys activity services " + PACKAGE_NAME_APP1 1904 + "/android.app.stubs.LocalForegroundService"; 1905 try { 1906 // Set APP1 to be background-restricted. 1907 setAppOp(PACKAGE_NAME_APP1, "RUN_ANY_IN_BACKGROUND", false); 1908 // Enable the FGS background startForeground() restriction. 1909 enableFgsRestriction(true, true, null); 1910 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1911 runWithShellPermissionIdentity(() -> { 1912 final BroadcastOptions options = BroadcastOptions.makeBasic(); 1913 // setTemporaryAppAllowlist API requires 1914 // START_FOREGROUND_SERVICES_FROM_BACKGROUND permission. 1915 options.setTemporaryAppAllowlist(TEMP_ALLOWLIST_DURATION_MS, 1916 TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED, 1917 REASON_ALARM_MANAGER_ALARM_CLOCK, 1918 ""); 1919 // Must use Shell to issue this command because Shell has 1920 // START_FOREGROUND_SERVICES_FROM_BACKGROUND permission. 1921 CommandReceiver.sendCommandWithBroadcastOptions(mContext, 1922 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1923 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null, 1924 options); 1925 }); 1926 // Although APP1 is background-restricted, FGS can still start because temp allowlist 1927 // reasonCode is REASON_ALARM_MANAGER_ALARM_CLOCK. 1928 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1929 waiter.doWait(WAITFOR_MSEC); 1930 String[] dumpLines = CtsAppTestUtils.executeShellCmd( 1931 mInstrumentation, dumpCommand).split("\n"); 1932 assertNotNull(CtsAppTestUtils.findLine(dumpLines, "isForeground=true")); 1933 // Stop the FGS. 1934 CommandReceiver.sendCommand(mContext, 1935 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 1936 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 1937 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 1938 WatchUidRunner.STATE_CACHED_EMPTY); 1939 } finally { 1940 uid1Watcher.finish(); 1941 CtsAppTestUtils.executeShellCmd(mInstrumentation, 1942 "appops reset --user " + mTestRunningUserId + " " + PACKAGE_NAME_APP1); 1943 // Sleep to let the temp allowlist expire so it won't affect next test case. 1944 SystemClock.sleep(TEMP_ALLOWLIST_DURATION_MS); 1945 } 1946 } 1947 1948 /** 1949 * FGS is already started because the app is temp allowlisted. Afterwards, when the 1950 * app becomes background-restricted, if the FGS start reasonCode is 1951 * REASON_ALARM_MANAGER_ALARM_CLOCK, FGS can keep running. 1952 */ 1953 @Presubmit 1954 @Test testAlarmClockFgsNotStoppedByBackgroundRestricted()1955 public void testAlarmClockFgsNotStoppedByBackgroundRestricted() throws Exception { 1956 testAlarmClockFgsNotStoppedByBackgroundRestrictedInternal(REASON_ALARM_MANAGER_ALARM_CLOCK); 1957 } 1958 1959 /** 1960 * FGS is already started because the app is temp allowlisted. Afterwards, when the 1961 * app becomes background-restricted, if the FGS start reasonCode is NOT 1962 * REASON_ALARM_MANAGER_ALARM_CLOCK, the FGS is stopped. 1963 */ 1964 @Presubmit 1965 @Test testFgsStoppedByBackgroundRestricted()1966 public void testFgsStoppedByBackgroundRestricted() throws Exception { 1967 testAlarmClockFgsNotStoppedByBackgroundRestrictedInternal(REASON_UNKNOWN); 1968 } 1969 testAlarmClockFgsNotStoppedByBackgroundRestrictedInternal(int reasonCode)1970 private void testAlarmClockFgsNotStoppedByBackgroundRestrictedInternal(int reasonCode) 1971 throws Exception { 1972 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 1973 PACKAGE_NAME_APP1, 0); 1974 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 1975 WAITFOR_MSEC); 1976 final String dumpCommand = "dumpsys activity services " + PACKAGE_NAME_APP1 1977 + "/android.app.stubs.LocalForegroundService"; 1978 final long shortWaitMsec = 5_000; 1979 try { 1980 // Enable the FGS background startForeground() restriction. 1981 enableFgsRestriction(true, true, null); 1982 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 1983 runWithShellPermissionIdentity(() -> { 1984 final BroadcastOptions options = BroadcastOptions.makeBasic(); 1985 // setTemporaryAppAllowlist API requires 1986 // START_FOREGROUND_SERVICES_FROM_BACKGROUND permission. 1987 options.setTemporaryAppAllowlist(TEMP_ALLOWLIST_DURATION_MS, 1988 TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED, 1989 reasonCode, 1990 ""); 1991 // Must use Shell to issue this command because Shell has 1992 // START_FOREGROUND_SERVICES_FROM_BACKGROUND permission. 1993 CommandReceiver.sendCommandWithBroadcastOptions(mContext, 1994 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 1995 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null, 1996 options); 1997 }); 1998 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 1999 waiter.doWait(WAITFOR_MSEC); 2000 String[] dumpLines = CtsAppTestUtils.executeShellCmd( 2001 mInstrumentation, dumpCommand).split("\n"); 2002 assertNotNull(CtsAppTestUtils.findLine(dumpLines, "isForeground=true")); 2003 2004 // Set APP1 to be background-restricted. 2005 setAppOp(PACKAGE_NAME_APP1, "RUN_ANY_IN_BACKGROUND", false); 2006 if (reasonCode == REASON_ALARM_MANAGER_ALARM_CLOCK) { 2007 SystemClock.sleep(shortWaitMsec); 2008 // Because the FGS start reasonCode is REASON_ALARM_MANAGER_ALARM_CLOCK, when the 2009 // app becomes background-restricted, its FGS can keep running. 2010 dumpLines = CtsAppTestUtils.executeShellCmd( 2011 mInstrumentation, dumpCommand).split("\n"); 2012 assertNotNull(CtsAppTestUtils.findLine(dumpLines, "isForeground=true")); 2013 // Stop the FGS. 2014 CommandReceiver.sendCommand(mContext, 2015 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 2016 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 2017 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 2018 WatchUidRunner.STATE_CACHED_EMPTY); 2019 } else { 2020 SystemClock.sleep(shortWaitMsec); 2021 // For other reasonCode, when the app is background-restricted, FGS is stopped. 2022 dumpLines = CtsAppTestUtils.executeShellCmd( 2023 mInstrumentation, dumpCommand).split("\n"); 2024 assertNull(CtsAppTestUtils.findLine(dumpLines, "isForeground=true")); 2025 } 2026 } finally { 2027 uid1Watcher.finish(); 2028 CtsAppTestUtils.executeShellCmd(mInstrumentation, 2029 "appops reset --user " + mTestRunningUserId + " " + PACKAGE_NAME_APP1); 2030 // Sleep to let the temp allowlist expire so it won't affect next test case. 2031 SystemClock.sleep(TEMP_ALLOWLIST_DURATION_MS); 2032 } 2033 } 2034 2035 /** 2036 * Test default_input_method is exempted from BG-FGS-start restriction. 2037 * @throws Exception 2038 */ 2039 @Presubmit 2040 @Test testFgsStartInputMethod()2041 public void testFgsStartInputMethod() throws Exception { 2042 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 2043 PACKAGE_NAME_APP1, 0); 2044 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 2045 WAITFOR_MSEC); 2046 final String defaultInputMethod = CtsAppTestUtils.executeShellCmd(mInstrumentation, 2047 "settings get --user " + mTestRunningUserId + " secure default_input_method"); 2048 try { 2049 // Enable the FGS background startForeground() restriction. 2050 enableFgsRestriction(true, true, null); 2051 // Start FGS in BG state. 2052 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 2053 CommandReceiver.sendCommand(mContext, 2054 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 2055 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 2056 // APP1 does not enter FGS state 2057 try { 2058 waiter.doWait(WAITFOR_MSEC); 2059 fail("Service should not enter foreground service state"); 2060 } catch (Exception e) { 2061 } 2062 2063 // Change default_input_method to PACKAGE_NAME_APP1. 2064 final ComponentName cn = new ComponentName(PACKAGE_NAME_APP1, "xxx"); 2065 CtsAppTestUtils.executeShellCmd(mInstrumentation, 2066 "settings put --user " + mTestRunningUserId + " secure default_input_method " 2067 + cn.flattenToShortString()); 2068 2069 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 2070 // Now it can start FGS. 2071 CommandReceiver.sendCommand(mContext, 2072 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 2073 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 2074 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 2075 waiter.doWait(WAITFOR_MSEC); 2076 // Stop the FGS. 2077 CommandReceiver.sendCommand(mContext, 2078 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 2079 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 2080 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 2081 } finally { 2082 uid1Watcher.finish(); 2083 CtsAppTestUtils.executeShellCmd(mInstrumentation, 2084 "settings put --user " + mTestRunningUserId + " secure default_input_method " 2085 + defaultInputMethod); 2086 } 2087 } 2088 2089 @Presubmit 2090 @Test testFgsStartInBackgroundRestrictions()2091 public void testFgsStartInBackgroundRestrictions() throws Exception { 2092 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 2093 PACKAGE_NAME_APP1, 0); 2094 ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo( 2095 PACKAGE_NAME_APP2, 0); 2096 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 2097 WAITFOR_MSEC); 2098 WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid, 2099 WAITFOR_MSEC); 2100 WaitForBroadcast waiter = new WaitForBroadcast(mInstrumentation.getTargetContext()); 2101 final String dumpCommand = "dumpsys activity services " + PACKAGE_NAME_APP2 2102 + "/android.app.stubs.LocalForegroundService"; 2103 final long shortWaitMsec = 5_000; 2104 try { 2105 // Enable the FGS background startForeground() restriction. 2106 enableFgsRestriction(true, true, null); 2107 2108 // Set background restriction for APP2 2109 setAppOp(PACKAGE_NAME_APP2, "RUN_ANY_IN_BACKGROUND", false); 2110 2111 // Start the APP1 into the TOP state. 2112 allowBgActivityStart(PACKAGE_NAME_APP1, true); 2113 CommandReceiver.sendCommand(mContext, 2114 CommandReceiver.COMMAND_START_ACTIVITY, 2115 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 2116 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 2117 WatchUidRunner.STATE_TOP); 2118 2119 // APP1 binds to APP2. 2120 CommandReceiver.sendCommand(mContext, CommandReceiver.COMMAND_BIND_SERVICE, 2121 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, Context.BIND_INCLUDE_CAPABILITIES, null); 2122 2123 // APP2 gets proc state BOUND_TOP. 2124 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 2125 WatchUidRunner.STATE_BOUND_TOP); 2126 2127 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 2128 2129 // START FGS in APP2. 2130 CommandReceiver.sendCommand(mContext, 2131 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 2132 PACKAGE_NAME_APP2, PACKAGE_NAME_APP2, 0, null); 2133 waiter.doWait(WAITFOR_MSEC); 2134 2135 SystemClock.sleep(shortWaitMsec); 2136 2137 String[] dumpLines = CtsAppTestUtils.executeShellCmd( 2138 mInstrumentation, dumpCommand).split("\n"); 2139 assertNotNull(CtsAppTestUtils.findLine(dumpLines, "isForeground=true")); 2140 2141 // Finish the activity in APP1 2142 CommandReceiver.sendCommand(mContext, 2143 CommandReceiver.COMMAND_STOP_ACTIVITY, 2144 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 2145 mInstrumentation.getUiAutomation().performGlobalAction( 2146 AccessibilityService.GLOBAL_ACTION_HOME); 2147 2148 // APP1 should have been cached state now. 2149 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 2150 WatchUidRunner.STATE_CACHED_EMPTY); 2151 2152 // Th FGS in APP2 should have been normal service state now. 2153 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 2154 WatchUidRunner.STATE_SERVICE); 2155 2156 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 2157 2158 // START FGS in APP1 2159 CommandReceiver.sendCommand(mContext, 2160 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 2161 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 2162 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 2163 WatchUidRunner.STATE_FG_SERVICE); 2164 waiter.doWait(WAITFOR_MSEC); 2165 2166 // APP2 should be in FGS state too now. 2167 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 2168 WatchUidRunner.STATE_FG_SERVICE); 2169 2170 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 2171 2172 // START FGS in APP2. 2173 CommandReceiver.sendCommand(mContext, 2174 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 2175 PACKAGE_NAME_APP2, PACKAGE_NAME_APP2, 0, null); 2176 waiter.doWait(WAITFOR_MSEC); 2177 2178 SystemClock.sleep(shortWaitMsec); 2179 2180 dumpLines = CtsAppTestUtils.executeShellCmd( 2181 mInstrumentation, dumpCommand).split("\n"); 2182 assertNotNull(CtsAppTestUtils.findLine(dumpLines, "isForeground=true")); 2183 2184 // Set background restriction for APP1. 2185 setAppOp(PACKAGE_NAME_APP1, "RUN_ANY_IN_BACKGROUND", false); 2186 2187 // Both of them should have normal service state now. 2188 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 2189 WatchUidRunner.STATE_SERVICE); 2190 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 2191 WatchUidRunner.STATE_SERVICE); 2192 } finally { 2193 uid1Watcher.finish(); 2194 uid2Watcher.finish(); 2195 CtsAppTestUtils.executeShellCmd(mInstrumentation, 2196 "appops reset --user " + mTestRunningUserId + " " + PACKAGE_NAME_APP1); 2197 CtsAppTestUtils.executeShellCmd(mInstrumentation, 2198 "appops reset --user " + mTestRunningUserId + " " + PACKAGE_NAME_APP2); 2199 } 2200 } 2201 2202 /** 2203 * When PowerExemptionManager.addToTemporaryAllowList() is called more than one time, the second 2204 * call can extend the duration of the first call if the first call has not expired yet. 2205 * @throws Exception 2206 */ 2207 @Presubmit 2208 @Test testOverlappedTempAllowList()2209 public void testOverlappedTempAllowList() throws Exception { 2210 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 2211 PACKAGE_NAME_APP1, 0); 2212 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 2213 WAITFOR_MSEC); 2214 try { 2215 // Enable the FGS background startForeground() restriction. 2216 enableFgsRestriction(true, true, null); 2217 // Start FGS in BG state. 2218 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 2219 CommandReceiver.sendCommand(mContext, 2220 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 2221 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 2222 // APP1 does not enter FGS state 2223 try { 2224 waiter.doWait(WAITFOR_MSEC); 2225 fail("Service should not enter foreground service state"); 2226 } catch (Exception e) { 2227 } 2228 2229 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 2230 runWithShellPermissionIdentity(() -> { 2231 mContext.getSystemService(PowerExemptionManager.class).addToTemporaryAllowList( 2232 PACKAGE_NAME_APP1, PowerExemptionManager.REASON_PUSH_MESSAGING, 2233 "", 10000); 2234 }); 2235 2236 SystemClock.sleep(5000); 2237 runWithShellPermissionIdentity(() -> { 2238 mContext.getSystemService(PowerExemptionManager.class).addToTemporaryAllowList( 2239 PACKAGE_NAME_APP1, PowerExemptionManager.REASON_PUSH_MESSAGING, 2240 "", 10000); 2241 }); 2242 SystemClock.sleep(5000); 2243 2244 // The first addToTemporaryAllowList()'s 10000ms duration has expired. 2245 // Now FGS start is allowed by second addToTemporaryAllowList()'s 10000ms duration. 2246 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 2247 // Now it can start FGS. 2248 CommandReceiver.sendCommand(mContext, 2249 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 2250 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 2251 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 2252 waiter.doWait(WAITFOR_MSEC); 2253 // Stop the FGS. 2254 CommandReceiver.sendCommand(mContext, 2255 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 2256 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 2257 uid1Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 2258 } finally { 2259 uid1Watcher.finish(); 2260 // allow temp allowlist to expire. 2261 SystemClock.sleep(5000); 2262 } 2263 } 2264 2265 /** 2266 * Test overlapped BroadcastOptions.setTemporaryAppAllowlist(). 2267 * This is similar to test case testOverlappedTempAllowList which is 2268 * PowerExemptionManager.addToTemporaryAllowList(). 2269 */ 2270 @Presubmit 2271 @Test testOverlappedTempAllowListByBroadcastOptions()2272 public void testOverlappedTempAllowListByBroadcastOptions() throws Exception { 2273 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 2274 PACKAGE_NAME_APP1, 0); 2275 ApplicationInfo app2Info = mContext.getPackageManager().getApplicationInfo( 2276 PACKAGE_NAME_APP2, 0); 2277 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 2278 WAITFOR_MSEC); 2279 WatchUidRunner uid2Watcher = new WatchUidRunner(mInstrumentation, app2Info.uid, 2280 WAITFOR_MSEC); 2281 try { 2282 // Enable the FGS background startForeground() restriction. 2283 enableFgsRestriction(true, true, null); 2284 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 2285 runWithShellPermissionIdentity(()-> { 2286 final BroadcastOptions options = BroadcastOptions.makeBasic(); 2287 // setTemporaryAppAllowlist API requires 2288 // START_FOREGROUND_SERVICES_FROM_BACKGROUND permission. 2289 options.setTemporaryAppAllowlist(10000, 2290 TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED, REASON_UNKNOWN, 2291 "10seconds_br_options"); 2292 // Must use Shell to issue this command because Shell has 2293 // START_FOREGROUND_SERVICES_FROM_BACKGROUND permission. 2294 CommandReceiver.sendCommandWithBroadcastOptions(mContext, 2295 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 2296 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null, 2297 options); 2298 }); 2299 2300 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 2301 waiter.doWait(WAITFOR_MSEC); 2302 // Stop the FGS. 2303 CommandReceiver.sendCommand(mContext, 2304 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 2305 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 2306 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 2307 WatchUidRunner.STATE_CACHED_EMPTY); 2308 2309 Thread.sleep(5000); 2310 // second BroadcastOptions.setTemporaryAppAllowlist() overlap with 2311 // first one. 2312 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 2313 runWithShellPermissionIdentity(()-> { 2314 final BroadcastOptions options = BroadcastOptions.makeBasic(); 2315 // setTemporaryAppAllowlist API requires 2316 // START_FOREGROUND_SERVICES_FROM_BACKGROUND permission. 2317 options.setTemporaryAppAllowlist(10000, 2318 TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED, REASON_UNKNOWN, 2319 "10seconds_br_options_2"); 2320 // Must use Shell to issue this command because Shell has 2321 // START_FOREGROUND_SERVICES_FROM_BACKGROUND permission. 2322 CommandReceiver.sendCommandWithBroadcastOptions(mContext, 2323 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 2324 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null, 2325 options); 2326 }); 2327 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 2328 waiter.doWait(WAITFOR_MSEC); 2329 // Stop the FGS. 2330 CommandReceiver.sendCommand(mContext, 2331 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 2332 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 2333 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, 2334 WatchUidRunner.STATE_CACHED_EMPTY); 2335 2336 Thread.sleep(5000); 2337 // The first BroadcastOptions.setTemporaryAppAllowlist()'s 10000ms duration has expired. 2338 // Now FGS start is allowed by second BroadcastOption's 10000ms duration. 2339 waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 2340 CommandReceiver.sendCommand(mContext, 2341 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE, 2342 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 2343 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 2344 waiter.doWait(WAITFOR_MSEC); 2345 // Stop the FGS. 2346 CommandReceiver.sendCommand(mContext, 2347 CommandReceiver.COMMAND_STOP_FOREGROUND_SERVICE, 2348 PACKAGE_NAME_APP1, PACKAGE_NAME_APP2, 0, null); 2349 uid2Watcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 2350 } finally { 2351 uid1Watcher.finish(); 2352 uid2Watcher.finish(); 2353 // Sleep 10 seconds to let the temp allowlist expire so it won't affect next test case. 2354 SystemClock.sleep(10000); 2355 } 2356 } 2357 2358 /** 2359 * IActivityManager.startService() is called directly (does not go through 2360 * {@link Context#startForegroundService(Intent)}, a spoofed packageName "com.google.android.as" 2361 * is used as callingPackage. Although "com.google.android.as" is allowlisted to start 2362 * foreground service from the background, but framework will detect this is a spoofed 2363 * packageName and disallow foreground service start from the background. 2364 * @throws Exception 2365 */ 2366 @Presubmit 2367 @Test testSpoofPackageName()2368 public void testSpoofPackageName() throws Exception { 2369 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 2370 PACKAGE_NAME_APP1, 0); 2371 WatchUidRunner uid1Watcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 2372 WAITFOR_MSEC); 2373 // CommandReceiver.COMMAND_START_FOREGROUND_SERVICE_SPOOF_PACKAGE_NAME needs access 2374 // to hidden API PackageManager.getAttentionServicePackageName() and 2375 // PackageManager.getSystemCaptionsServicePackageName(), so we need to call 2376 // hddenApiSettings.set("*") to exempt the hidden APIs. 2377 SettingsSession<String> hiddenApiSettings = new SettingsSession<>( 2378 Settings.Global.getUriFor( 2379 Settings.Global.HIDDEN_API_BLACKLIST_EXEMPTIONS), 2380 Settings.Global::getString, Settings.Global::putString); 2381 hiddenApiSettings.set("*"); 2382 try { 2383 // Enable the FGS background startForeground() restriction. 2384 enableFgsRestriction(true, true, null); 2385 // Start FGS in BG state. 2386 WaitForBroadcast waiter = createBroadcastWaiter(ACTION_START_FGS_RESULT); 2387 CommandReceiver.sendCommand(mContext, 2388 CommandReceiver.COMMAND_START_FOREGROUND_SERVICE_SPOOF_PACKAGE_NAME, 2389 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0, null); 2390 // APP1 does not enter FGS state 2391 try { 2392 waiter.doWait(WAITFOR_MSEC); 2393 fail("Service should not enter foreground service state"); 2394 } catch (Exception e) { 2395 } 2396 } finally { 2397 uid1Watcher.finish(); 2398 if (hiddenApiSettings != null) { 2399 hiddenApiSettings.close(); 2400 } 2401 } 2402 } 2403 2404 @Test testStartMediaPlaybackFromBg()2405 public void testStartMediaPlaybackFromBg() throws Exception { 2406 // TODO(b/380297485): Remove this assumption check once NotificationListeners 2407 // support visible background users. 2408 assumeFalse("NotificationListeners do not support visible background users", 2409 mUserHelper.isVisibleBackgroundUser()); 2410 NotificationHelper notificationHelper = new NotificationHelper(mContext); 2411 ApplicationInfo app1Info = mContext.getPackageManager().getApplicationInfo( 2412 PACKAGE_NAME_APP1, 0); 2413 WatchUidRunner uidWatcher = new WatchUidRunner(mInstrumentation, app1Info.uid, 2414 WAITFOR_MSEC); 2415 // Grant notification listener access in order to query 2416 // MediaSessionManager.getActiveSessions(). 2417 notificationHelper.enableListener(STUB_PACKAGE_NAME); 2418 try { 2419 // Enable the FGS background startForeground() restriction. 2420 enableFgsRestriction(true, true, null); 2421 2422 final Bundle bundle = new Bundle(); 2423 final CountDownLatch latch = new CountDownLatch(1); 2424 bundle.putParcelable(Intent.EXTRA_REMOTE_CALLBACK, 2425 new RemoteCallback(result -> latch.countDown())); 2426 CommandReceiver.sendCommand(mContext, 2427 CommandReceiver.COMMAND_CREATE_ACTIVE_MEDIA_SESSION, 2428 PACKAGE_NAME_APP1, PACKAGE_NAME_APP1, 0 /* flags */, bundle); 2429 if (!latch.await(WAITFOR_MSEC, TimeUnit.MILLISECONDS)) { 2430 fail("Timed out waiting for the test app to receive the start_media_playback cmd"); 2431 } 2432 uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_CACHED_EMPTY); 2433 2434 final MediaSessionManager mediaSessionManager = mTargetContext.getSystemService( 2435 MediaSessionManager.class); 2436 final List<MediaController> mediaControllers = mediaSessionManager.getActiveSessions( 2437 new ComponentName(STUB_PACKAGE_NAME, TestNotificationListener.class.getName())); 2438 final MediaController controller = findMediaControllerForPkg(mediaControllers, 2439 PACKAGE_NAME_APP1); 2440 // Send "play" command and verify that the app moves to FGS state. 2441 controller.getTransportControls().play(); 2442 uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 2443 controller.getTransportControls().pause(); 2444 uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_SERVICE); 2445 controller.getTransportControls().play(); 2446 uidWatcher.waitFor(WatchUidRunner.CMD_PROCSTATE, WatchUidRunner.STATE_FG_SERVICE); 2447 2448 controller.getTransportControls().stop(); 2449 } finally { 2450 notificationHelper.disableListener(STUB_PACKAGE_NAME); 2451 uidWatcher.finish(); 2452 //DEFAULT_MEDIA_SESSION_CALLBACK_FGS_WHILE_IN_USE_TEMP_ALLOW_DURATION_MS = 10000ms 2453 SystemClock.sleep(10000); 2454 } 2455 } 2456 findMediaControllerForPkg(List<MediaController> mediaControllers, String packageName)2457 private MediaController findMediaControllerForPkg(List<MediaController> mediaControllers, 2458 String packageName) { 2459 for (MediaController controller : mediaControllers) { 2460 if (packageName.equals(controller.getPackageName())) { 2461 return controller; 2462 } 2463 } 2464 return null; 2465 } 2466 2467 /** 2468 * Turn on the FGS BG-launch restriction. DeviceConfig can turn on restriction on the whole 2469 * device (across all apps). AppCompat can turn on restriction on a single app package. 2470 * 2471 * @param enable true to turn on restriction, false to turn off. 2472 * @param useDeviceConfig true to use DeviceConfig, false to use AppCompat CHANGE ID. 2473 * @param packageName the packageName if using AppCompat CHANGE ID. 2474 */ enableFgsRestriction( final boolean enable, boolean useDeviceConfig, String packageName)2475 private void enableFgsRestriction( 2476 final boolean enable, boolean useDeviceConfig, String packageName) throws Exception { 2477 if (useDeviceConfig) { 2478 runWithShellPermissionIdentity( 2479 () -> { 2480 DeviceConfig.setProperty( 2481 "activity_manager", 2482 KEY_DEFAULT_FGS_STARTS_RESTRICTION_ENABLED, 2483 Boolean.toString(enable), 2484 false); 2485 TestUtils.waitUntil( 2486 "Failed to set property" 2487 + KEY_DEFAULT_FGS_STARTS_RESTRICTION_ENABLED 2488 + " to " 2489 + enable, 2490 WAITFOR_MSEC, 2491 () -> { 2492 final String isEnabled = 2493 DeviceConfig.getProperty( 2494 "activity_manager", 2495 KEY_DEFAULT_FGS_STARTS_RESTRICTION_ENABLED); 2496 return String.valueOf(enable).equals(isEnabled); 2497 }); 2498 }); 2499 } else { 2500 CtsAppTestUtils.executeShellCmd(mInstrumentation, 2501 "am compat " + (enable ? "enable" : "disable") 2502 + " FGS_BG_START_RESTRICTION_CHANGE_ID " + packageName); 2503 } 2504 } 2505 2506 /** 2507 * Clean up the FGS BG-launch restriction. 2508 * 2509 * @param packageName the packageName that will have its changeid override reset. 2510 */ resetFgsRestriction(String packageName)2511 private void resetFgsRestriction(String packageName) 2512 throws Exception { 2513 CtsAppTestUtils.executeShellCmd(mInstrumentation, 2514 "am compat reset FGS_BG_START_RESTRICTION_CHANGE_ID " + packageName); 2515 } 2516 2517 /** 2518 * SYSTEM_ALERT_WINDOW permission will allow both BG-activity start and BG-FGS start. 2519 * Some cases we want to grant this permission to allow activity start to bring the app up to 2520 * TOP state. 2521 * Some cases we want to revoke this permission to test other BG-FGS-launch exemptions. 2522 */ allowBgActivityStart(String packageName, boolean allow)2523 private void allowBgActivityStart(String packageName, boolean allow) throws Exception { 2524 final String permission = android.Manifest.permission.SYSTEM_ALERT_WINDOW; 2525 if (allow) { 2526 PermissionUtils.grantPermission(packageName, permission); 2527 } else { 2528 PermissionUtils.revokePermission(packageName, permission); 2529 } 2530 2531 TestUtils.waitUntil( 2532 "Timed out waiting for " 2533 + packageName 2534 + "'s " 2535 + permission 2536 + " permission to be " 2537 + allow, 2538 WAITFOR_MSEC, 2539 () -> { 2540 return PermissionUtils.isGranted(packageName, permission) == allow; 2541 }); 2542 } 2543 setFgsStartForegroundTimeout(int timeoutMs)2544 private void setFgsStartForegroundTimeout(int timeoutMs) throws Exception { 2545 runWithShellPermissionIdentity(() -> { 2546 DeviceConfig.setProperty("activity_manager", 2547 KEY_FGS_START_FOREGROUND_TIMEOUT, 2548 Integer.toString(timeoutMs), false); 2549 } 2550 ); 2551 } 2552 setAppOp(String packageName, String opStr, boolean allow)2553 private void setAppOp(String packageName, String opStr, boolean allow) throws Exception { 2554 CtsAppTestUtils.executeShellCmd(mInstrumentation, 2555 "appops set --user " + mTestRunningUserId + " " + packageName + " " + opStr + " " 2556 + (allow ? "allow" : "deny")); 2557 } 2558 setPushMessagingOverQuotaBehavior( int type)2559 private void setPushMessagingOverQuotaBehavior( 2560 /* @PowerExemptionManager.TempAllowListType */ int type) throws Exception { 2561 runWithShellPermissionIdentity(() -> { 2562 DeviceConfig.setProperty("activity_manager", 2563 KEY_PUSH_MESSAGING_OVER_QUOTA_BEHAVIOR, 2564 Integer.toString(type), false); 2565 } 2566 ); 2567 // Sleep 2 seconds to allow the device config change to be applied. 2568 SystemClock.sleep(2000); 2569 } 2570 getPushMessagingOverQuotaBehavior()2571 private int getPushMessagingOverQuotaBehavior() throws Exception { 2572 final String defaultBehaviorStr = CtsAppTestUtils.executeShellCmd(mInstrumentation, 2573 "device_config get activity_manager " 2574 + KEY_PUSH_MESSAGING_OVER_QUOTA_BEHAVIOR).trim(); 2575 int defaultBehavior = TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_NOT_ALLOWED; 2576 if (!defaultBehaviorStr.equals("null")) { 2577 try { 2578 defaultBehavior = Integer.parseInt(defaultBehaviorStr); 2579 } catch (NumberFormatException e) { 2580 Log.e("ActivityManagerFgsBgStartTest", 2581 "getPushMessagingOverQuotaBehavior:", e); 2582 } 2583 } 2584 return defaultBehavior; 2585 } 2586 enableFgsSawRestriction(boolean enable, String packageName)2587 private void enableFgsSawRestriction(boolean enable, String packageName) 2588 throws Exception { 2589 runWithShellPermissionIdentity(() -> { 2590 DeviceConfig.setProperty("activity_manager", 2591 "fgs_saw_restrictions_enabled", 2592 Boolean.toString(enable), false); 2593 } 2594 ); 2595 final String action = enable ? "enable" : "disable"; 2596 CtsAppTestUtils.executeShellCmd(mInstrumentation, "am compat " + action 2597 + " --no-kill FGS_SAW_RESTRICTIONS " + packageName); 2598 } 2599 resetFgsSawRestrictionEnabled(String packageName)2600 private void resetFgsSawRestrictionEnabled(String packageName) { 2601 mInstrumentation.getUiAutomation().executeShellCommand( 2602 "am compat reset --no-kill FGS_SAW_RESTRICTIONS " + packageName); 2603 } 2604 createBroadcastWaiter(String action)2605 private WaitForBroadcast createBroadcastWaiter(String action) throws Exception { 2606 final WaitForBroadcast waiter = new WaitForBroadcast(mTargetContext); 2607 runShellCommand(mInstrumentation, "am wait-for-broadcast-barrier"); 2608 waiter.prepare(action); 2609 return waiter; 2610 } 2611 } 2612