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

Commit 222c7b1e authored by Pradeep Sawlani's avatar Pradeep Sawlani Committed by Android (Google) Code Review
Browse files

Merge changes from topic "stopmediafgs" into main

* changes:
  am: Add set-media-foreground-service command.
  ActivityManagerService: Add method to set media fgs inactive.
parents ef9885ae ff38543e
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -1149,6 +1149,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
+41 −0
Original line number Diff line number Diff line
@@ -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--) {
+9 −0
Original line number Diff line number Diff line
@@ -17922,6 +17922,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) {
+49 −0
Original line number Diff line number Diff line
@@ -39,6 +39,8 @@ import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_CRI
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_LOW;
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_MODERATE;
import static com.android.internal.app.procstats.ProcessStats.ADJ_MEM_FACTOR_NORMAL;
import static com.android.media.flags.Flags.enableNotifyingActivityManagerWithMediaSessionStatusChange;
import static com.android.media.flags.Flags.FLAG_ENABLE_NOTIFYING_ACTIVITY_MANAGER_WITH_MEDIA_SESSION_STATUS_CHANGE;
import static com.android.server.am.ActivityManagerDebugConfig.LOG_WRITER_INFO;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
@@ -445,6 +447,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
                    return runCapabilities(pw);
                case "set-app-zygote-preload-timeout":
                    return runSetAppZygotePreloadTimeout(pw);
                case "set-media-foreground-service":
                    return runSetMediaForegroundService(pw);
                default:
                    return handleDefaultCommands(cmd);
            }
@@ -454,6 +458,48 @@ final class ActivityManagerShellCommand extends ShellCommand {
        return -1;
    }

    int runSetMediaForegroundService(PrintWriter pw) throws RemoteException {
        mInternal.enforceCallingPermission(
                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE,
                "runSetMediaForegroundService()");
        final PrintWriter err = getErrPrintWriter();
        if (!enableNotifyingActivityManagerWithMediaSessionStatusChange()) {
            err.println("Error: flag "
                    + FLAG_ENABLE_NOTIFYING_ACTIVITY_MANAGER_WITH_MEDIA_SESSION_STATUS_CHANGE
                    + " not enabled");
            return -1;
        }
        int userId = UserHandle.USER_CURRENT;
        final String cmd = getNextArgRequired();
        if ("inactive".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'");
                        return -1;
                    }
                } else {
                    err.println("Error: Unknown option: " + opt);
                    return -1;
                }
            }
            final String pkgName = getNextArgRequired();
            final int notificationId = Integer.parseInt(getNextArgRequired());
            if (notificationId == 0) {
                err.println("Error: notification id cannot be zero");
                return -1;
            }
            mInternal.mInternal.notifyInactiveMediaForegroundService(pkgName,
                    userId, notificationId);
            return 0;
        }
        err.println("Error: Unknown set-media-foreground-service command: " + cmd);
        return -1;
    }

    int runSetAppZygotePreloadTimeout(PrintWriter pw) throws RemoteException {
        final String timeout = getNextArgRequired();
        final int timeoutMs = Integer.parseInt(timeout);
@@ -4637,6 +4683,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.");
            Intent.printIntentArgsHelp(pw, "");
        }
    }