Allow preventing unrestricted Apps from being Stopped
This CL adds a flag to allow toggling the behavior on whether or not
the foreground service task manager should show a stop button for
unrestricted apps.
Bug: 230449539
Test: Manual - device_config put systemui \
show_stop_button_for_user_allowlisted_apps true|false
Test: atest FgsManagerControllerTest
Change-Id: I4cfe54933d7c6807a7ffbac9ee709c7d8d6b83d3
Merged-In: I4cfe54933d7c6807a7ffbac9ee709c7d8d6b83d3
This commit is contained in:
committed by
Jordan Demeulenaere
parent
ea08a5217b
commit
dcd089d3e7
@@ -548,6 +548,12 @@ public final class SystemUiDeviceConfigFlags {
|
|||||||
*/
|
*/
|
||||||
public static final String TASK_MANAGER_SHOW_FOOTER_DOT = "task_manager_show_footer_dot";
|
public static final String TASK_MANAGER_SHOW_FOOTER_DOT = "task_manager_show_footer_dot";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (boolean) Whether the task manager should show a stop button if the app is allowlisted
|
||||||
|
* by the user.
|
||||||
|
*/
|
||||||
|
public static final String TASK_MANAGER_SHOW_STOP_BUTTON_FOR_USER_ALLOWLISTED_APPS =
|
||||||
|
"show_stop_button_for_user_allowlisted_apps";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* (boolean) Whether the clipboard overlay is enabled.
|
* (boolean) Whether the clipboard overlay is enabled.
|
||||||
|
|||||||
@@ -40,11 +40,13 @@ import android.widget.Button
|
|||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.annotation.GuardedBy
|
import androidx.annotation.GuardedBy
|
||||||
|
import androidx.annotation.VisibleForTesting
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_ENABLED
|
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_ENABLED
|
||||||
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_SHOW_FOOTER_DOT
|
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_SHOW_FOOTER_DOT
|
||||||
|
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.TASK_MANAGER_SHOW_STOP_BUTTON_FOR_USER_ALLOWLISTED_APPS
|
||||||
import com.android.internal.jank.InteractionJankMonitor
|
import com.android.internal.jank.InteractionJankMonitor
|
||||||
import com.android.systemui.Dumpable
|
import com.android.systemui.Dumpable
|
||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
@@ -87,6 +89,7 @@ class FgsManagerController @Inject constructor(
|
|||||||
private val LOG_TAG = FgsManagerController::class.java.simpleName
|
private val LOG_TAG = FgsManagerController::class.java.simpleName
|
||||||
private const val DEFAULT_TASK_MANAGER_ENABLED = true
|
private const val DEFAULT_TASK_MANAGER_ENABLED = true
|
||||||
private const val DEFAULT_TASK_MANAGER_SHOW_FOOTER_DOT = false
|
private const val DEFAULT_TASK_MANAGER_SHOW_FOOTER_DOT = false
|
||||||
|
private const val DEFAULT_TASK_MANAGER_SHOW_STOP_BUTTON_FOR_USER_ALLOWLISTED_APPS = true
|
||||||
}
|
}
|
||||||
|
|
||||||
var changesSinceDialog = false
|
var changesSinceDialog = false
|
||||||
@@ -96,6 +99,8 @@ class FgsManagerController @Inject constructor(
|
|||||||
private set
|
private set
|
||||||
var showFooterDot = false
|
var showFooterDot = false
|
||||||
private set
|
private set
|
||||||
|
var showStopBtnForUserAllowlistedApps = false
|
||||||
|
private set
|
||||||
|
|
||||||
private val lock = Any()
|
private val lock = Any()
|
||||||
|
|
||||||
@@ -163,6 +168,9 @@ class FgsManagerController @Inject constructor(
|
|||||||
isAvailable = it.getBoolean(TASK_MANAGER_ENABLED, isAvailable)
|
isAvailable = it.getBoolean(TASK_MANAGER_ENABLED, isAvailable)
|
||||||
showFooterDot =
|
showFooterDot =
|
||||||
it.getBoolean(TASK_MANAGER_SHOW_FOOTER_DOT, showFooterDot)
|
it.getBoolean(TASK_MANAGER_SHOW_FOOTER_DOT, showFooterDot)
|
||||||
|
showStopBtnForUserAllowlistedApps = it.getBoolean(
|
||||||
|
TASK_MANAGER_SHOW_STOP_BUTTON_FOR_USER_ALLOWLISTED_APPS,
|
||||||
|
showStopBtnForUserAllowlistedApps)
|
||||||
}
|
}
|
||||||
|
|
||||||
isAvailable = deviceConfigProxy.getBoolean(
|
isAvailable = deviceConfigProxy.getBoolean(
|
||||||
@@ -173,6 +181,10 @@ class FgsManagerController @Inject constructor(
|
|||||||
NAMESPACE_SYSTEMUI,
|
NAMESPACE_SYSTEMUI,
|
||||||
TASK_MANAGER_SHOW_FOOTER_DOT, DEFAULT_TASK_MANAGER_SHOW_FOOTER_DOT
|
TASK_MANAGER_SHOW_FOOTER_DOT, DEFAULT_TASK_MANAGER_SHOW_FOOTER_DOT
|
||||||
)
|
)
|
||||||
|
showStopBtnForUserAllowlistedApps = deviceConfigProxy.getBoolean(
|
||||||
|
NAMESPACE_SYSTEMUI,
|
||||||
|
TASK_MANAGER_SHOW_STOP_BUTTON_FOR_USER_ALLOWLISTED_APPS,
|
||||||
|
DEFAULT_TASK_MANAGER_SHOW_STOP_BUTTON_FOR_USER_ALLOWLISTED_APPS)
|
||||||
|
|
||||||
dumpManager.registerDumpable(this)
|
dumpManager.registerDumpable(this)
|
||||||
|
|
||||||
@@ -275,6 +287,20 @@ class FgsManagerController @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
@JvmName("getNumVisibleButtons")
|
||||||
|
internal fun getNumVisibleButtons(): Int {
|
||||||
|
synchronized(lock) {
|
||||||
|
return getNumVisibleButtonsLocked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getNumVisibleButtonsLocked(): Int {
|
||||||
|
return runningServiceTokens.keys.count {
|
||||||
|
it.uiControl != UIControl.HIDE_BUTTON && currentProfileIds.contains(it.userId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun shouldUpdateFooterVisibility() = dialog == null
|
fun shouldUpdateFooterVisibility() = dialog == null
|
||||||
|
|
||||||
fun showDialog(viewLaunchedFrom: View?) {
|
fun showDialog(viewLaunchedFrom: View?) {
|
||||||
@@ -505,6 +531,13 @@ class FgsManagerController @Inject constructor(
|
|||||||
PowerExemptionManager.REASON_PROC_STATE_PERSISTENT_UI,
|
PowerExemptionManager.REASON_PROC_STATE_PERSISTENT_UI,
|
||||||
PowerExemptionManager.REASON_ROLE_DIALER,
|
PowerExemptionManager.REASON_ROLE_DIALER,
|
||||||
PowerExemptionManager.REASON_SYSTEM_MODULE -> UIControl.HIDE_BUTTON
|
PowerExemptionManager.REASON_SYSTEM_MODULE -> UIControl.HIDE_BUTTON
|
||||||
|
|
||||||
|
PowerExemptionManager.REASON_ALLOWLISTED_PACKAGE ->
|
||||||
|
if (showStopBtnForUserAllowlistedApps) {
|
||||||
|
UIControl.NORMAL
|
||||||
|
} else {
|
||||||
|
UIControl.HIDE_BUTTON
|
||||||
|
}
|
||||||
else -> UIControl.NORMAL
|
else -> UIControl.NORMAL
|
||||||
}
|
}
|
||||||
uiControlInitialized = true
|
uiControlInitialized = true
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
package com.android.systemui.qs;
|
package com.android.systemui.qs;
|
||||||
|
|
||||||
|
import static android.os.PowerExemptionManager.REASON_ALLOWLISTED_PACKAGE;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
import static org.mockito.ArgumentMatchers.argThat;
|
import static org.mockito.ArgumentMatchers.argThat;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
@@ -34,6 +36,7 @@ import android.content.pm.PackageManager;
|
|||||||
import android.content.pm.UserInfo;
|
import android.content.pm.UserInfo;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
import android.os.UserHandle;
|
||||||
import android.provider.DeviceConfig;
|
import android.provider.DeviceConfig;
|
||||||
import android.testing.AndroidTestingRunner;
|
import android.testing.AndroidTestingRunner;
|
||||||
import android.testing.TestableLooper;
|
import android.testing.TestableLooper;
|
||||||
@@ -222,7 +225,41 @@ public class FgsManagerControllerTest extends SysuiTestCase {
|
|||||||
Assert.assertEquals(2, mFmc.getNumRunningPackages());
|
Assert.assertEquals(2, mFmc.getNumRunningPackages());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testButtonVisibilityOnShowAllowlistButtonFlagChange() throws Exception {
|
||||||
|
setUserProfiles(0);
|
||||||
|
setBackgroundRestrictionExemptionReason("pkg", 12345, REASON_ALLOWLISTED_PACKAGE);
|
||||||
|
|
||||||
|
final Binder binder = new Binder();
|
||||||
|
setShowStopButtonForUserAllowlistedApps(true);
|
||||||
|
mIForegroundServiceObserver.onForegroundStateChanged(binder, "pkg", 0, true);
|
||||||
|
Assert.assertEquals(1, mFmc.getNumVisibleButtons());
|
||||||
|
|
||||||
|
mIForegroundServiceObserver.onForegroundStateChanged(binder, "pkg", 0, false);
|
||||||
|
Assert.assertEquals(0, mFmc.getNumVisibleButtons());
|
||||||
|
|
||||||
|
setShowStopButtonForUserAllowlistedApps(false);
|
||||||
|
mIForegroundServiceObserver.onForegroundStateChanged(binder, "pkg", 0, true);
|
||||||
|
Assert.assertEquals(0, mFmc.getNumVisibleButtons());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setShowStopButtonForUserAllowlistedApps(boolean enable) {
|
||||||
|
mDeviceConfigProxyFake.setProperty(DeviceConfig.NAMESPACE_SYSTEMUI,
|
||||||
|
SystemUiDeviceConfigFlags.TASK_MANAGER_SHOW_STOP_BUTTON_FOR_USER_ALLOWLISTED_APPS,
|
||||||
|
enable ? "true" : "false", false);
|
||||||
|
mBackgroundExecutor.advanceClockToLast();
|
||||||
|
mBackgroundExecutor.runAllReady();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setBackgroundRestrictionExemptionReason(String pkgName, int uid, int reason)
|
||||||
|
throws Exception {
|
||||||
|
Mockito.doReturn(uid)
|
||||||
|
.when(mPackageManager)
|
||||||
|
.getPackageUidAsUser(pkgName, UserHandle.getUserId(uid));
|
||||||
|
Mockito.doReturn(reason)
|
||||||
|
.when(mIActivityManager)
|
||||||
|
.getBackgroundRestrictionExemptionReason(uid);
|
||||||
|
}
|
||||||
|
|
||||||
FgsManagerController createFgsManagerController() throws RemoteException {
|
FgsManagerController createFgsManagerController() throws RemoteException {
|
||||||
ArgumentCaptor<IForegroundServiceObserver> iForegroundServiceObserverArgumentCaptor =
|
ArgumentCaptor<IForegroundServiceObserver> iForegroundServiceObserverArgumentCaptor =
|
||||||
|
|||||||
Reference in New Issue
Block a user