Merge "Suppress the prompt for the apps with high bg battery usage" into tm-dev

This commit is contained in:
Jing Ji
2022-03-31 01:27:25 +00:00
committed by Android (Google) Code Review
2 changed files with 96 additions and 1 deletions

View File

@@ -186,6 +186,12 @@ public final class AppRestrictionController {
*/
private static final boolean ENABLE_SHOW_FOREGROUND_SERVICE_MANAGER = true;
/**
* Whether or not to show the action to the foreground service manager when
* posting the notification for background restriction.
*/
private static final boolean ENABLE_SHOW_FGS_MANAGER_ACTION_ON_BG_RESTRICTION = false;
private final Context mContext;
private final HandlerThread mBgHandlerThread;
private final BgHandler mBgHandler;
@@ -665,6 +671,14 @@ public final class AppRestrictionController {
static final String KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_TO_BG_RESTRICTED =
DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "prompt_fgs_with_noti_to_bg_restricted";
/**
* The behavior for an app with a FGS and its notification is still showing, when the system
* detects it's running for a very long time, should we prompt the user.
* {@code true} - we'll show the prompt to user, {@code false} - we'll not show it.
*/
static final String KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING =
DEVICE_CONFIG_SUBNAMESPACE_PREFIX + "prompt_fgs_with_noti_on_long_running";
/**
* The list of packages to be exempted from all these background restrictions.
*/
@@ -686,6 +700,11 @@ public final class AppRestrictionController {
*/
static final long DEFAULT_BG_LONG_FGS_NOTIFICATION_MINIMAL_INTERVAL_MS = 30 * ONE_DAY;
/**
* Default value to {@link #mBgPromptFgsWithNotiOnLongRunning}.
*/
static final boolean DEFAULT_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING = false;
/**
* Default value to {@link #mBgPromptFgsWithNotiToBgRestricted}.
*/
@@ -711,6 +730,11 @@ public final class AppRestrictionController {
*/
volatile boolean mBgPromptFgsWithNotiToBgRestricted;
/**
* @see #KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING.
*/
volatile boolean mBgPromptFgsWithNotiOnLongRunning;
ConstantsObserver(Handler handler, Context context) {
super(handler);
mDefaultBgPromptFgsWithNotiToBgRestricted = context.getResources().getBoolean(
@@ -736,6 +760,9 @@ public final class AppRestrictionController {
case KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_TO_BG_RESTRICTED:
updateBgPromptFgsWithNotiToBgRestricted();
break;
case KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING:
updateBgPromptFgsWithNotiOnLongRunning();
break;
case KEY_BG_RESTRICTION_EXEMPTED_PACKAGES:
updateBgRestrictionExemptedPackages();
break;
@@ -772,6 +799,7 @@ public final class AppRestrictionController {
updateBgAbusiveNotificationMinimalInterval();
updateBgLongFgsNotificationMinimalInterval();
updateBgPromptFgsWithNotiToBgRestricted();
updateBgPromptFgsWithNotiOnLongRunning();
updateBgRestrictionExemptedPackages();
}
@@ -807,6 +835,13 @@ public final class AppRestrictionController {
mDefaultBgPromptFgsWithNotiToBgRestricted);
}
private void updateBgPromptFgsWithNotiOnLongRunning() {
mBgPromptFgsWithNotiOnLongRunning = DeviceConfig.getBoolean(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING,
DEFAULT_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING);
}
private void updateBgRestrictionExemptedPackages() {
final String settings = DeviceConfig.getString(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
@@ -1691,7 +1726,9 @@ public final class AppRestrictionController {
return;
}
}
if (ENABLE_SHOW_FOREGROUND_SERVICE_MANAGER && hasForegroundServices) {
if (ENABLE_SHOW_FOREGROUND_SERVICE_MANAGER
&& ENABLE_SHOW_FGS_MANAGER_ACTION_ON_BG_RESTRICTION
&& hasForegroundServices) {
final Intent trampoline = new Intent(ACTION_FGS_MANAGER_TRAMPOLINE);
trampoline.setPackage("android");
trampoline.putExtra(Intent.EXTRA_PACKAGE_NAME, packageName);
@@ -1716,6 +1753,13 @@ public final class AppRestrictionController {
void postLongRunningFgsIfNecessary(String packageName, int uid) {
PendingIntent pendingIntent;
if (!mBgController.mConstantsObserver.mBgPromptFgsWithNotiOnLongRunning
&& mBgController.hasForegroundServiceNotifications(packageName, uid)) {
if (DEBUG_BG_RESTRICTION_CONTROLLER) {
Slog.i(TAG, "Not prompt long-running due to FGS with notification");
}
return;
}
if (ENABLE_SHOW_FOREGROUND_SERVICE_MANAGER) {
final Intent intent = new Intent(ACTION_SHOW_FOREGROUND_SERVICE_MANAGER);
intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);

View File

@@ -1067,6 +1067,8 @@ public final class BackgroundRestrictionTest {
final int testUid2 = UserHandle.getUid(testUser2, TEST_PACKAGE_APPID_BASE + testPkgIndex2);
final int testPid2 = 1235;
final int fgsNotificationId = 1000;
final long windowMs = 2_000;
final long thresholdMs = 1_000;
final long shortMs = 100;
@@ -1074,6 +1076,7 @@ public final class BackgroundRestrictionTest {
DeviceConfigSession<Boolean> longRunningFGSMonitor = null;
DeviceConfigSession<Long> longRunningFGSWindow = null;
DeviceConfigSession<Long> longRunningFGSThreshold = null;
DeviceConfigSession<Boolean> longRunningFGSWithNotification = null;
try {
longRunningFGSMonitor = new DeviceConfigSession<>(
@@ -1097,6 +1100,13 @@ public final class BackgroundRestrictionTest {
AppFGSPolicy.DEFAULT_BG_FGS_LONG_RUNNING_THRESHOLD);
longRunningFGSThreshold.set(thresholdMs);
longRunningFGSWithNotification = new DeviceConfigSession<>(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
ConstantsObserver.KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING,
DeviceConfig::getBoolean,
ConstantsObserver.DEFAULT_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING);
longRunningFGSWithNotification.set(true);
// Basic case
mAppFGSTracker.onForegroundServiceStateChanged(testPkgName1, testUid1,
testPid1, true);
@@ -1196,10 +1206,42 @@ public final class BackgroundRestrictionTest {
mAppFGSTracker.onForegroundServiceStateChanged(testPkgName1, testUid1,
testPid1, false);
checkNotificationGone(testPkgName1, timeout(windowMs), notificationId);
// Start over with the flag to not show prompt when it has an active notification.
clearInvocations(mInjector.getNotificationManager());
mBgRestrictionController.resetRestrictionSettings();
longRunningFGSWithNotification.set(false);
// Start an FGS with notification.
mAppFGSTracker.onForegroundServiceStateChanged(testPkgName1, testUid1,
testPid1, true);
mAppFGSTracker.onForegroundServiceNotificationUpdated(
testPkgName1, testUid1, fgsNotificationId);
mAppFGSTracker.mNotificationListener.onNotificationPosted(new StatusBarNotification(
testPkgName1, null, fgsNotificationId, null, testUid1, testPid1,
new Notification(), UserHandle.of(testUser1), null, mCurrentTimeMillis), null);
// Verify we won't prompt the user because it has a visible FGS notification.
checkNotificationShown(
new String[] {testPkgName1}, timeout(windowMs * 2).times(0), false);
// Pretend we have the notification dismissed.
mAppFGSTracker.onForegroundServiceNotificationUpdated(
testPkgName1, testUid1, -fgsNotificationId);
// Verify we have the notification.
notificationId = checkNotificationShown(
new String[] {testPkgName1}, timeout(windowMs * 2).times(2), true)[0];
// Stop the FGS.
mAppFGSTracker.onForegroundServiceStateChanged(testPkgName1, testUid1,
testPid1, false);
checkNotificationGone(testPkgName1, timeout(windowMs), notificationId);
} finally {
closeIfNotNull(longRunningFGSMonitor);
closeIfNotNull(longRunningFGSWindow);
closeIfNotNull(longRunningFGSThreshold);
closeIfNotNull(longRunningFGSWithNotification);
}
}
@@ -1225,6 +1267,7 @@ public final class BackgroundRestrictionTest {
DeviceConfigSession<Long> longRunningFGSThreshold = null;
DeviceConfigSession<Long> mediaPlaybackFGSThreshold = null;
DeviceConfigSession<Long> locationFGSThreshold = null;
DeviceConfigSession<Boolean> longRunningFGSWithNotification = null;
doReturn(testPkgName1).when(mInjector).getPackageName(testPid1);
doReturn(testPkgName2).when(mInjector).getPackageName(testPid2);
@@ -1265,6 +1308,13 @@ public final class BackgroundRestrictionTest {
AppFGSPolicy.DEFAULT_BG_FGS_LOCATION_THRESHOLD);
locationFGSThreshold.set(thresholdMs);
longRunningFGSWithNotification = new DeviceConfigSession<>(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
ConstantsObserver.KEY_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING,
DeviceConfig::getBoolean,
ConstantsObserver.DEFAULT_BG_PROMPT_FGS_WITH_NOTIFICATION_ON_LONG_RUNNING);
longRunningFGSWithNotification.set(true);
// Long-running FGS with type "location", but ran for a very short time.
runTestLongFGSExemptionOnce(testPkgName1, testUid1, testPid1,
FOREGROUND_SERVICE_TYPE_LOCATION, 0, null, OP_NONE, null, null,
@@ -1372,6 +1422,7 @@ public final class BackgroundRestrictionTest {
closeIfNotNull(longRunningFGSThreshold);
closeIfNotNull(mediaPlaybackFGSThreshold);
closeIfNotNull(locationFGSThreshold);
closeIfNotNull(longRunningFGSWithNotification);
}
}