diff options
| author | 2024-11-07 04:22:44 +0000 | |
|---|---|---|
| committer | 2024-11-07 04:22:44 +0000 | |
| commit | 74e02acd2b2e1d39d87a4e437a151b0cfc330cfc (patch) | |
| tree | 787f2e428a97160139f5a45d0d3eceee573955b8 | |
| parent | aa3c2f7593f00a9ece251e00560bf2b76d8ea817 (diff) | |
| parent | bcdf21f5c060b29be58010d242eb08bb672a57fc (diff) | |
Merge "Apps can opt in to be stoppable in the task manager" into main
5 files changed, 95 insertions, 4 deletions
diff --git a/core/res/res/values/stoppable_fgs_system_apps.xml b/core/res/res/values/stoppable_fgs_system_apps.xml new file mode 100644 index 000000000000..165ff61c7b3e --- /dev/null +++ b/core/res/res/values/stoppable_fgs_system_apps.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources> + <!-- A list of system apps whose FGS can be stopped in the task manager. --> + <string-array translatable="false" name="stoppable_fgs_system_apps"> + </string-array> + <!-- stoppable_fgs_system_apps which is supposed to be overridden by vendor --> + <string-array translatable="false" name="vendor_stoppable_fgs_system_apps"> + </string-array> +</resources> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index aa08d5e2313e..db81a3be440f 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1306,6 +1306,8 @@ <java-symbol type="array" name="vendor_policy_exempt_apps" /> <java-symbol type="array" name="cloneable_apps" /> <java-symbol type="array" name="config_securityStatePackages" /> + <java-symbol type="array" name="stoppable_fgs_system_apps" /> + <java-symbol type="array" name="vendor_stoppable_fgs_system_apps" /> <java-symbol type="drawable" name="default_wallpaper" /> <java-symbol type="drawable" name="default_lock_wallpaper" /> diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig index 3bf3e24a2ba6..87ea2a7ab2ae 100644 --- a/packages/SystemUI/aconfig/systemui.aconfig +++ b/packages/SystemUI/aconfig/systemui.aconfig @@ -1743,3 +1743,13 @@ flag { description: "An implementation of shortcut customizations through shortcut helper." bug: "365064144" } + +flag { + name: "stoppable_fgs_system_app" + namespace: "systemui" + description: "System app with foreground service can opt in to be stoppable." + bug: "376564917" + metadata { + purpose: PURPOSE_BUGFIX + } +} diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/FgsManagerControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/FgsManagerControllerTest.java index 16ae4662c2d4..0356422bda04 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/FgsManagerControllerTest.java +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/FgsManagerControllerTest.java @@ -42,6 +42,7 @@ import android.content.pm.UserInfo; import android.os.Binder; import android.os.RemoteException; import android.os.UserHandle; +import android.platform.test.annotations.EnableFlags; import android.provider.DeviceConfig; import android.testing.TestableLooper; @@ -49,6 +50,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; +import com.android.systemui.Flags; import com.android.systemui.SysuiTestCase; import com.android.systemui.animation.DialogTransitionAnimator; import com.android.systemui.broadcast.BroadcastDispatcher; @@ -315,13 +317,36 @@ public class FgsManagerControllerTest extends SysuiTestCase { } @Test + @EnableFlags(Flags.FLAG_STOPPABLE_FGS_SYSTEM_APP) + public void testButtonVisibilityOfStoppableApps() throws Exception { + setUserProfiles(0); + setBackgroundRestrictionExemptionReason("pkg", 12345, REASON_ALLOWLISTED_PACKAGE); + setBackgroundRestrictionExemptionReason("vendor_pkg", 67890, REASON_ALLOWLISTED_PACKAGE); + + // Same as above, but apps are opt-in to be stoppable + setStoppableApps(new String[] {"pkg"}, /* vendor */ false); + setStoppableApps(new String[] {"vendor_pkg"}, /* vendor */ true); + + final Binder binder = new Binder(); + setShowStopButtonForUserAllowlistedApps(true); + // Both are foreground. + mIForegroundServiceObserver.onForegroundStateChanged(binder, "pkg", 0, true); + mIForegroundServiceObserver.onForegroundStateChanged(binder, "vendor_pkg", 0, true); + Assert.assertEquals(2, mFmc.visibleButtonsCount()); + + // The vendor package is no longer foreground. Only `pkg` remains. + mIForegroundServiceObserver.onForegroundStateChanged(binder, "vendor_pkg", 0, false); + Assert.assertEquals(1, mFmc.visibleButtonsCount()); + } + + @Test public void testShowUserVisibleJobsOnCreation() { // Test when the default is on. mDeviceConfigProxyFake.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI, SystemUiDeviceConfigFlags.TASK_MANAGER_SHOW_USER_VISIBLE_JOBS, "true", false); FgsManagerController fmc = new FgsManagerControllerImpl( - mContext, + mContext.getResources(), mMainExecutor, mBackgroundExecutor, mSystemClock, @@ -348,7 +373,7 @@ public class FgsManagerControllerTest extends SysuiTestCase { SystemUiDeviceConfigFlags.TASK_MANAGER_SHOW_USER_VISIBLE_JOBS, "false", false); fmc = new FgsManagerControllerImpl( - mContext, + mContext.getResources(), mMainExecutor, mBackgroundExecutor, mSystemClock, @@ -446,6 +471,11 @@ public class FgsManagerControllerTest extends SysuiTestCase { .getBackgroundRestrictionExemptionReason(uid); } + private void setStoppableApps(String[] packageNames, boolean vendor) throws Exception { + overrideResource(vendor ? com.android.internal.R.array.vendor_stoppable_fgs_system_apps + : com.android.internal.R.array.stoppable_fgs_system_apps, packageNames); + } + FgsManagerController createFgsManagerController() throws RemoteException { ArgumentCaptor<IForegroundServiceObserver> iForegroundServiceObserverArgumentCaptor = ArgumentCaptor.forClass(IForegroundServiceObserver.class); @@ -455,7 +485,7 @@ public class FgsManagerControllerTest extends SysuiTestCase { ArgumentCaptor.forClass(BroadcastReceiver.class); FgsManagerController result = new FgsManagerControllerImpl( - mContext, + mContext.getResources(), mMainExecutor, mBackgroundExecutor, mSystemClock, diff --git a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt index a1071907cd3d..2a5ffc6cc391 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt @@ -27,6 +27,7 @@ import android.content.Intent import android.content.IntentFilter import android.content.pm.PackageManager import android.content.pm.UserInfo +import android.content.res.Resources import android.graphics.drawable.Drawable import android.os.IBinder import android.os.PowerExemptionManager @@ -54,6 +55,7 @@ import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_ import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_SHOW_USER_VISIBLE_JOBS import com.android.internal.jank.InteractionJankMonitor import com.android.systemui.Dumpable +import com.android.systemui.Flags; import com.android.systemui.res.R import com.android.systemui.animation.DialogCuj import com.android.systemui.animation.DialogTransitionAnimator @@ -137,7 +139,7 @@ interface FgsManagerController { @SysUISingleton class FgsManagerControllerImpl @Inject constructor( - private val context: Context, + @Main private val resources: Resources, @Main private val mainExecutor: Executor, @Background private val backgroundExecutor: Executor, private val systemClock: SystemClock, @@ -223,6 +225,14 @@ class FgsManagerControllerImpl @Inject constructor( private val userVisibleJobObserver = UserVisibleJobObserver() + private val stoppableApps by lazy { resources + .getStringArray(com.android.internal.R.array.stoppable_fgs_system_apps) + } + + private val vendorStoppableApps by lazy { resources + .getStringArray(com.android.internal.R.array.vendor_stoppable_fgs_system_apps) + } + override fun init() { synchronized(lock) { if (initialized) { @@ -725,9 +735,22 @@ class FgsManagerControllerImpl @Inject constructor( } else -> UIControl.NORMAL } + // If the app wants to be a good citizen by being stoppable, even if the category it + // belongs to is exempted for background restriction, let it be stoppable by user. + if (Flags.stoppableFgsSystemApp()) { + if (isStoppableApp(packageName)) { + uiControl = UIControl.NORMAL + } + } + uiControlInitialized = true } + fun isStoppableApp(packageName: String): Boolean { + return stoppableApps.contains(packageName) || + vendorStoppableApps.contains(packageName) + } + override fun equals(other: Any?): Boolean { if (other !is UserPackage) { return false |