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

Commit 9210bc85 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Implement #10744011: Serialize running of background services

Added some code to the activity manager to keep track of
services that are launching and limit the number that can
be launched concurrently.  This only comes into play under
specific circumstances: when the service launch is a background
request (so timing is not important) and its process is not
already running at a high priority.

In this case, we have a list of services that are currently
launching and when that gets too big we start delaying the
launch of future services until currently launching ones are
finished.

There are some important tuning parameters for this: how many
background services we allow to launch concurrently (currently
1 on low-ram devices, 3 on other devices), and how long we
wait for a background service to run before consider it to be
a more long-running service and go on to the next pending
launch (currently set to 15 seconds).

Also while in here, did some cleanup of the service code:

- A little refactoring to make per-user data cleaner.
- Switch to ArrayMap.

Change-Id: I09f372eb5e0f81a8de7c64f8320af41e84b90aa3
parent 49580cf1
Loading
Loading
Loading
Loading
+355 −152

File changed.

Preview size limit exceeded, changes collapsed.

+27 −1
Original line number Diff line number Diff line
@@ -528,6 +528,32 @@ final class ProcessRecord {
        return stringName = sb.toString();
    }

    public String makeAdjReason() {
        StringBuilder sb = new StringBuilder(128);
        sb.append('(').append(adjType).append(')');
        if (adjSource != null || adjTarget != null) {
            sb.append(' ');
            if (adjTarget instanceof ComponentName) {
                sb.append(((ComponentName)adjTarget).flattenToShortString());
            } else if (adjTarget != null) {
                sb.append(adjTarget.toString());
            } else {
                sb.append("{null}");
            }
            sb.append("<=");
            if (adjSource instanceof ProcessRecord) {
                sb.append("Proc{");
                sb.append(((ProcessRecord)adjSource).toShortString());
                sb.append("}");
            } else if (adjSource != null) {
                sb.append(adjSource.toString());
            } else {
                sb.append("{null}");
            }
        }
        return sb.toString();
    }

    /*
     *  Return true if package has been added false if not
     */
+13 −4
Original line number Diff line number Diff line
@@ -85,11 +85,14 @@ final class ServiceRecord extends Binder {
    ProcessRecord app;      // where this service is running or null.
    ProcessRecord isolatedProc; // keep track of isolated process, if requested
    ProcessStats.ServiceState tracker; // tracking service execution, may be null
    boolean delayed;        // are we waiting to start this service in the background?
    boolean isForeground;   // is service currently in foreground mode?
    int foregroundId;       // Notification ID of last foreground req.
    Notification foregroundNoti; // Notification record of foreground state.
    long lastActivity;      // last time there was some activity on the service.
    long startingBgTimeout;  // time at which we scheduled this for a delayed start.
    boolean startRequested; // someone explicitly called start?
    boolean delayedStop;    // service has been stopped but is in a delayed start?
    boolean stopIfKilled;   // last onStart() said to stop if service killed?
    boolean callStart;      // last onStart() has asked to alway be called on restart.
    int executeNesting;     // number of outstanding operations keeping foreground.
@@ -220,6 +223,9 @@ final class ServiceRecord extends Binder {
        if (isolatedProc != null) {
            pw.print(prefix); pw.print("isolatedProc="); pw.println(isolatedProc);
        }
        if (delayed) {
            pw.print(prefix); pw.print("delayed="); pw.println(delayed);
        }
        if (isForeground || foregroundId != 0) {
            pw.print(prefix); pw.print("isForeground="); pw.print(isForeground);
                    pw.print(" foregroundId="); pw.print(foregroundId);
@@ -227,14 +233,17 @@ final class ServiceRecord extends Binder {
        }
        pw.print(prefix); pw.print("createTime=");
                TimeUtils.formatDuration(createTime, nowReal, pw);
                pw.print(" lastActivity=");
                TimeUtils.formatDuration(lastActivity, now, pw);
                pw.print(" startingBgTimeout=");
                TimeUtils.formatDuration(startingBgTimeout, now, pw);
                pw.println();
        pw.print(prefix); pw.print("restartTime=");
        pw.print(prefix); pw.print("lastActivity=");
                TimeUtils.formatDuration(lastActivity, now, pw);
                pw.print(" restartTime=");
                TimeUtils.formatDuration(restartTime, now, pw);
                pw.print(" createdFromFg="); pw.println(createdFromFg);
        if (startRequested || lastStartId != 0) {
        if (startRequested || delayedStop || lastStartId != 0) {
            pw.print(prefix); pw.print("startRequested="); pw.print(startRequested);
                    pw.print(" delayedStop="); pw.print(delayedStop);
                    pw.print(" stopIfKilled="); pw.print(stopIfKilled);
                    pw.print(" callStart="); pw.print(callStart);
                    pw.print(" lastStartId="); pw.println(lastStartId);