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

Commit db92608d authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Fix issue #11168649: LRU logic for Chrome renderers seems...

...not to work on KitKat (was: Janky exit animation)

Reworking the LRU list (splitting it into an activity vs. empty
section) accidentally broken the old behavior of "client activity"
processes being prioritized with activity processes.  In fact, we
were no longer marking "client activity" processes at all.

In this change, we rework how we manage "client activity" processes
by putting them on the main activity LRU section.  This is generally
simple -- ActiveServices now keeps track of whether a process is
a "client activity" process based on its bindings, and updateLruProcess
treats these as regular activity processes.  However, we don't want
to allow processes doing this to spam our LRU list so that we lose
everything else, so there is some additional complexity in managing
that list where we spread client activity processes across is so
that the intermingle with other activity processes.

The rest of the change is fairly simple -- the old client activity
process management is gone, but that doesn't matter because it wasn't
actually running any more.  There is a new argument to updateLruProcess
to indicate a client process it comes from (since we now need to update
this based on bindings) which is just used to limit how high in the
LRU list we can move things.  The ProcessRecord.hasActivities field is
simply removied, because ProcessRecord.activities.size() > 0 means the
same thing, and that is actually what all of the key mechanisms are using
at this point.

Finally, note there is some commented out code of a new way to manage
the LRU movement.  This isn't in use, but something I would like to
move to in the next release so it is staying there for now for further
development.

Change-Id: Id8a21b4e32bb5aa9c8e7d443de4b658487cfbe18
parent 714ba345
Loading
Loading
Loading
Loading
+53 −2
Original line number Diff line number Diff line
@@ -564,7 +564,7 @@ public final class ActiveServices {
                    if (r.isForeground) {
                        r.isForeground = false;
                        if (r.app != null) {
                            mAm.updateLruProcessLocked(r.app, false, false);
                            mAm.updateLruProcessLocked(r.app, false, null);
                            updateServiceForegroundLocked(r.app, true);
                        }
                    }
@@ -597,6 +597,42 @@ public final class ActiveServices {
        }
    }

    private boolean updateServiceClientActivitiesLocked(ProcessRecord proc,
            ConnectionRecord modCr) {
        if (modCr != null && modCr.binding.client != null) {
            if (modCr.binding.client.activities.size() <= 0) {
                // This connection is from a client without activities, so adding
                // and removing is not interesting.
                return false;
            }
        }

        boolean anyClientActivities = false;
        for (int i=proc.services.size()-1; i>=0 && !anyClientActivities; i--) {
            ServiceRecord sr = proc.services.valueAt(i);
            for (int conni=sr.connections.size()-1; conni>=0 && !anyClientActivities; conni--) {
                ArrayList<ConnectionRecord> clist = sr.connections.valueAt(conni);
                for (int cri=clist.size()-1; cri>=0; cri--) {
                    ConnectionRecord cr = clist.get(cri);
                    if (cr.binding.client == null || cr.binding.client == proc) {
                        // Binding to ourself is not interesting.
                        continue;
                    }
                    if (cr.binding.client.activities.size() > 0) {
                        anyClientActivities = true;
                        break;
                    }
                }
            }
        }
        if (anyClientActivities != proc.hasClientActivities) {
            proc.hasClientActivities = anyClientActivities;
            mAm.updateLruProcessLocked(proc, anyClientActivities, null);
            return true;
        }
        return false;
    }

    int bindServiceLocked(IApplicationThread caller, IBinder token,
            Intent service, String resolvedType,
            IServiceConnection connection, int flags, int userId) {
@@ -698,6 +734,9 @@ public final class ActiveServices {
            if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
                b.client.hasAboveClient = true;
            }
            if (s.app != null) {
                updateServiceClientActivitiesLocked(s.app, c);
            }
            clist = mServiceConnections.get(binder);
            if (clist == null) {
                clist = new ArrayList<ConnectionRecord>();
@@ -714,6 +753,7 @@ public final class ActiveServices {

            if (s.app != null) {
                // This could have made the service more important.
                mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities, b.client);
                mAm.updateOomAdjLocked(s.app);
            }

@@ -1316,7 +1356,8 @@ public final class ActiveServices {

        app.services.add(r);
        bumpServiceExecutingLocked(r, execInFg, "create");
        mAm.updateLruProcessLocked(app, true, false);
        mAm.updateLruProcessLocked(app, false, null);
        mAm.updateOomAdjLocked();

        boolean created = false;
        try {
@@ -1601,6 +1642,9 @@ public final class ActiveServices {
            if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
                b.client.updateHasAboveClientLocked();
            }
            if (s.app != null) {
                updateServiceClientActivitiesLocked(s.app, c);
            }
        }
        clist = mServiceConnections.get(binder);
        if (clist != null) {
@@ -1621,6 +1665,13 @@ public final class ActiveServices {
                    && b.intent.hasBound) {
                try {
                    bumpServiceExecutingLocked(s, false, "unbind");
                    if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0
                            && s.app.setProcState <= ActivityManager.PROCESS_STATE_RECEIVER) {
                        // If this service's process is not already in the cached list,
                        // then update it in the LRU list here because this may be causing
                        // it to go down there and we want it to start out near the top.
                        mAm.updateLruProcessLocked(s.app, false, null);
                    }
                    mAm.updateOomAdjLocked(s.app);
                    b.intent.hasBound = false;
                    // Assume the client doesn't want to know about a rebind;
+161 −69

File changed.

Preview size limit exceeded, changes collapsed.

+4 −4

File changed.

Preview size limit exceeded, changes collapsed.

+2 −1
Original line number Diff line number Diff line
@@ -905,7 +905,8 @@ public final class ActivityStackSupervisor {
        if (idx < 0) {
            app.activities.add(r);
        }
        mService.updateLruProcessLocked(app, true, true);
        mService.updateLruProcessLocked(app, true, null);
        mService.updateOomAdjLocked();

        final ActivityStack stack = r.task.stack;
        try {
+2 −1

File changed.

Preview size limit exceeded, changes collapsed.

Loading