Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a4faf620 authored by Pradeep Sawlani's avatar Pradeep Sawlani
Browse files

ActivityManagerService: Add method to set media fgs active.



Changes adds
-  New method in activity manager service to set
   foreground service of type media playback active. This method
   is expected to be called from MediaSessionService when media session
   is "user-engaged" from "user-disengaged" state. This method will move
   service to foreground.
-  New command in am
   am set-media-foreground-service inactive [--user USER_ID] <PACKAGE> <NOTIFICATION_ID>
   Notification ID associated with media service can be found out
   using 'dumpsys activity services` and looking for foregrondId.

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: If4c31c9ecae9bda0c1731dab0cc13d88e1225e1a
Signed-off-by: default avatarPradeep Sawlani <sawlani@google.com>
parent 222c7b1e
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -1163,6 +1163,19 @@ public abstract class ActivityManagerInternal {
    public abstract void notifyInactiveMediaForegroundService(@NonNull String packageName,
            @UserIdInt int userId, int notificationId);

    /**
     * Notifies that a media service associated with a media session has transitioned to a
     * "user-engaged" state. Upon receiving this notification, service will transition to 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 service.
     * @param userId The user ID associated with the service.
     * @param notificationId The ID of the media notification associated with the service.
     */
    public abstract void notifyActiveMediaForegroundService(@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
+40 −0
Original line number Diff line number Diff line
@@ -9319,6 +9319,46 @@ public final class ActiveServices {
            Slog.e(TAG, "stopForegroundServiceDelegateLocked delegate does not exist");
        }
    }
    /**
     * Handles notifications from MediaSessionService about active media service.
     * This method evaluates the provided information and transitions corresponding service to
     * foreground state.
     *
     * @param packageName The package name of the app running the service.
     * @param userId The user ID associated with the service.
     * @param notificationId The ID of the media notification associated with the service.
     */
    void notifyActiveMediaForegroundServiceLocked(@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) {
                // foregroundServiceType is cleared when media session is user-disengaged
                // and calls notifyInactiveMediaForegroundService->setServiceForegroundInnerLocked.
                if (sr.foregroundServiceType
                        == ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE
                        && sr.foregroundId == notificationId) {
                    if (DEBUG_FOREGROUND_SERVICE) {
                        Slog.d(TAG, "Moving media service to foreground for package "
                                + packageName);
                    }
                    setServiceForegroundInnerLocked(sr, sr.foregroundId,
                             sr.foregroundNoti, /* flags */ 0,
                             ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK,
                             /* callingUidStart */ 0);
                }
            }
        }
    }

    /**
     * Handles notifications from MediaSessionService about inactive media foreground services.
+9 −0
Original line number Diff line number Diff line
@@ -17922,6 +17922,15 @@ public class ActivityManagerService extends IActivityManager.Stub
            }
        }
        @Override
        public void notifyActiveMediaForegroundService(@NonNull String packageName,
                @UserIdInt int userId, int notificationId) {
            synchronized (ActivityManagerService.this) {
                mServices.notifyActiveMediaForegroundServiceLocked(packageName, userId,
                        notificationId);
            }
        }
        @Override
        public void notifyInactiveMediaForegroundService(@NonNull String packageName,
                @UserIdInt int userId, int notificationId) {
+12 −7
Original line number Diff line number Diff line
@@ -471,14 +471,14 @@ final class ActivityManagerShellCommand extends ShellCommand {
        }
        int userId = UserHandle.USER_CURRENT;
        final String cmd = getNextArgRequired();
        if ("inactive".equals(cmd)) {
        if ("inactive".equals(cmd) || "active".equals(cmd)) {
            String opt;
            while ((opt = getNextOption()) != null) {
                if (opt.equals("--user")) {
                    userId = UserHandle.parseUserArg(getNextArgRequired());
                    if (userId == UserHandle.USER_ALL) {
                        err.println(
                                "Error: Can't set media fgs inactive with user 'all'");
                                "Error: Can't set media fgs with user 'all'");
                        return -1;
                    }
                } else {
@@ -492,8 +492,13 @@ final class ActivityManagerShellCommand extends ShellCommand {
                err.println("Error: notification id cannot be zero");
                return -1;
            }
            if ("inactive".equals(cmd)) {
                mInternal.mInternal.notifyInactiveMediaForegroundService(pkgName,
                        userId, notificationId);
            } else {
                mInternal.mInternal.notifyActiveMediaForegroundService(pkgName,
                        userId, notificationId);
            }
            return 0;
        }
        err.println("Error: Unknown set-media-foreground-service command: " + cmd);
@@ -4683,9 +4688,9 @@ final class ActivityManagerShellCommand extends ShellCommand {
            pw.println("         --protobuf: format output using protobuffer");
            pw.println("  set-app-zygote-preload-timeout <TIMEOUT_IN_MS>");
            pw.println("         Set the timeout for preloading code in the app-zygote");
            pw.println("  set-media-foreground-service inactive [--user USER_ID]"
                    + " <PACKAGE> <NOTIFICATION_ID>");
            pw.println("         Set an app's media foreground service inactive.");
            pw.println("  set-media-foreground-service inactive|active [--user USER_ID] <PACKAGE>"
                            + " <NOTIFICATION_ID>");
            pw.println("         Set an app's media service inactive or active.");
            Intent.printIntentArgsHelp(pw, "");
        }
    }