Allow apps to bypass Power Save restrictions when launched from a Notification's PendingIntent.
This scenario typically happens when the device is on Doze Mode and a
notification action is triggered from a Wear device.
In a nutshell, the workflow is:
- ProcessRecord has a flag telling whether a process has "whitelist
management" privileges.
- When NotificationManager binds a new NotificationListenerService, it
sets the BIND_ALLOW_WHITELIST_MANAGEMENT flag.
- On bind(), ActiveService asserts that only system apps can set that
flag.
- On computeOomAdjLocked(), ActivityManagerService sets the
ProcessRecord flag if necessary.
- Upon creating a notification, NotificationManager calls AM to mark its
PendingIntents as coming from a notification.
- When PendingIntentRecord sends it to the target, it checks if it's
from a notification and if so calls AM to do the temp whitelist.
- On unbind(), ActiveService removes the ProcessRecord flag if necessary.
Fixes: 28818704
Change-Id: I00d46036a2cbb73f7f733fd35bf0b743a02807a1
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 53c5a6d..dc85dd7 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -16,6 +16,10 @@
package com.android.server.notification;
+import static android.content.Context.BIND_ALLOW_WHITELIST_MANAGEMENT;
+import static android.content.Context.BIND_AUTO_CREATE;
+import static android.content.Context.BIND_FOREGROUND_SERVICE;
+
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.PendingIntent;
@@ -43,7 +47,6 @@
import android.os.UserManager;
import android.provider.Settings;
import android.text.TextUtils;
-import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;
@@ -56,7 +59,6 @@
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
-import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
@@ -681,7 +683,7 @@
};
if (!mContext.bindServiceAsUser(intent,
serviceConnection,
- Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
+ BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE | BIND_ALLOW_WHITELIST_MANAGEMENT,
new UserHandle(userid))) {
mServicesBinding.remove(servicesBindingTag);
Slog.w(TAG, "Unable to bind " + getCaption() + " service: " + intent);