summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Pradeep Sawlani <sawlani@google.com> 2024-10-31 19:54:48 -0700
committer Pradeep Sawlani <sawlani@google.com> 2024-11-13 15:22:45 -0800
commitc939f2cb680d3b74f4050e35ad51a89c49199758 (patch)
treefdc8494dab69201adbed1c575911558a85dde2f8
parent7c2a45be868b5c441f9c3cc06f44a2c37f6ea433 (diff)
ActivityManagerService: Add method to set media fgs inactive.
Changes adds a new method in activity manager service to set foreground service of type media playback inactive. This method is expected to be called from MediaSessionService when media session is "user-disengaged" for certain amount of time (>10mins). This method will move foreground service to background and allowing application to be subject to other system policies to save resources. Flag: com.android.media.flags.enable_notifying_activity_manager_with_media_session_status_change BUG: 281762171 Test: atest cts/tests/app/src/android/app/cts/ActivityManagerNotifyMediaFGSTypeTest.java Change-Id: If4e60dabeec6cc595703c0d07369d7526fe8d862
-rw-r--r--core/java/android/app/ActivityManagerInternal.java14
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java41
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java9
3 files changed, 64 insertions, 0 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index f80121d0c9b6..d9f8d33f0545 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -1150,6 +1150,20 @@ public abstract class ActivityManagerInternal {
public abstract void stopForegroundServiceDelegate(@NonNull ServiceConnection connection);
/**
+ * Notifies that a media foreground service associated with a media session has
+ * transitioned to a "user-disengaged" state.
+ * Upon receiving this notification, service may be removed from the foreground state. It
+ * should only be called by {@link com.android.server.media.MediaSessionService}
+ *
+ * @param packageName The package name of the app running the media foreground service.
+ * @param userId The user ID associated with the foreground service.
+ * @param notificationId The ID of the media notification associated with the foreground
+ * service.
+ */
+ public abstract void notifyInactiveMediaForegroundService(@NonNull String packageName,
+ @UserIdInt int userId, int notificationId);
+
+ /**
* Same as {@link android.app.IActivityManager#startProfile(int userId)}, but it would succeed
* even if the profile is disabled - it should only be called by
* {@link com.android.server.devicepolicy.DevicePolicyManagerService} when starting a profile
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 3f540ad43da1..ab3ab159ba12 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -115,6 +115,7 @@ import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_
import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM;
import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_REPORTED__REQUEST_TYPE__BIND;
import static com.android.internal.util.FrameworkStatsLog.SERVICE_REQUEST_EVENT_REPORTED__REQUEST_TYPE__START;
+import static com.android.media.flags.Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOREGROUND_SERVICE;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
@@ -9319,6 +9320,46 @@ public final class ActiveServices {
}
}
+ /**
+ * Handles notifications from MediaSessionService about inactive media foreground services.
+ * This method evaluates the provided information and determines whether to stop the
+ * corresponding foreground service.
+ *
+ * @param packageName The package name of the app running the foreground service.
+ * @param userId The user ID associated with the foreground service.
+ * @param notificationId The ID of the media notification associated with the foreground
+ * service.
+ */
+ void notifyInactiveMediaForegroundServiceLocked(@NonNull String packageName,
+ @UserIdInt int userId, int notificationId) {
+ if (!enableNotifyingActivityManagerWithMediaSessionStatusChange()) {
+ return;
+ }
+
+ final ServiceMap smap = mServiceMap.get(userId);
+ if (smap == null) {
+ return;
+ }
+ final int serviceSize = smap.mServicesByInstanceName.size();
+ for (int i = 0; i < serviceSize; i++) {
+ final ServiceRecord sr = smap.mServicesByInstanceName.valueAt(i);
+ if (sr.appInfo.packageName.equals(packageName) && sr.isForeground) {
+ if (sr.foregroundServiceType
+ == ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK
+ && sr.foregroundId == notificationId) {
+ if (DEBUG_FOREGROUND_SERVICE) {
+ Slog.d(TAG, "Forcing media foreground service to background for package "
+ + packageName);
+ }
+ setServiceForegroundInnerLocked(sr, /* id */ 0,
+ /* notification */ null, /* flags */ 0,
+ /* foregroundServiceType */ 0, /* callingUidStart */ 0);
+ }
+ }
+ }
+ }
+
+
private static void getClientPackages(ServiceRecord sr, ArraySet<String> output) {
var connections = sr.getConnections();
for (int conni = connections.size() - 1; conni >= 0; conni--) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 1c3569dd52d0..54f84aed3718 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -17911,6 +17911,15 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
+ public void notifyInactiveMediaForegroundService(@NonNull String packageName,
+ @UserIdInt int userId, int notificationId) {
+ synchronized (ActivityManagerService.this) {
+ mServices.notifyInactiveMediaForegroundServiceLocked(packageName, userId,
+ notificationId);
+ }
+ }
+
+ @Override
public ArraySet<String> getClientPackages(String servicePackageName) {
synchronized (ActivityManagerService.this) {
return mServices.getClientPackagesLocked(servicePackageName);