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

Commit eb3c49a8 authored by Jing Ji's avatar Jing Ji
Browse files

Perform oomAdjUpdate prior to scheduling service transactions

To ensure the apps executing the service transactions(start/stop etc.)
are in the correct proc state and unfrozen.

Bug: 191429032
Test: atest MockingOomAdjusterTests
Test: atest CtsAppTestCases
Change-Id: I32271adbe75afe377014f036e017667a7857dbf9
Merged-In: I32271adbe75afe377014f036e017667a7857dbf9
parent 5b1b2b15
Loading
Loading
Loading
Loading
+40 −32
Original line number Original line Diff line number Diff line
@@ -3334,7 +3334,13 @@ public final class ActiveServices {
        }
        }
    }
    }


    private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
    /**
     * Bump the given service record into executing state.
     * @param oomAdjReason The caller requests it to perform the oomAdjUpdate if it's not null.
     * @return {@code true} if it performed oomAdjUpdate.
     */
    private boolean bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why,
            @Nullable String oomAdjReason) {
        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, ">>> EXECUTING "
        if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, ">>> EXECUTING "
                + why + " of " + r + " in app " + r.app);
                + why + " of " + r + " in app " + r.app);
        else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING, ">>> EXECUTING "
        else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING, ">>> EXECUTING "
@@ -3383,9 +3389,19 @@ public final class ActiveServices {
                }
                }
            }
            }
        }
        }
        boolean oomAdjusted = false;
        if (oomAdjReason != null && r.app != null
                && r.app.mState.getCurProcState() > ActivityManager.PROCESS_STATE_SERVICE) {
            // Force an immediate oomAdjUpdate, so the client app could be in the correct process
            // state before doing any service related transactions
            mAm.enqueueOomAdjTargetLocked(r.app);
            mAm.updateOomAdjPendingTargetsLocked(oomAdjReason);
            oomAdjusted = true;
        }
        r.executeFg |= fg;
        r.executeFg |= fg;
        r.executeNesting++;
        r.executeNesting++;
        r.executingStart = now;
        r.executingStart = now;
        return oomAdjusted;
    }
    }


    private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
    private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
@@ -3398,8 +3414,8 @@ public final class ActiveServices {
                + " rebind=" + rebind);
                + " rebind=" + rebind);
        if ((!i.requested || rebind) && i.apps.size() > 0) {
        if ((!i.requested || rebind) && i.apps.size() > 0) {
            try {
            try {
                bumpServiceExecutingLocked(r, execInFg, "bind");
                bumpServiceExecutingLocked(r, execInFg, "bind",
                r.app.mState.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
                        OomAdjuster.OOM_ADJ_REASON_BIND_SERVICE);
                r.app.getThread().scheduleBindService(r, i.intent.getIntent(), rebind,
                r.app.getThread().scheduleBindService(r, i.intent.getIntent(), rebind,
                        r.app.mState.getReportedProcState());
                        r.app.mState.getReportedProcState());
                if (!rebind) {
                if (!rebind) {
@@ -3867,14 +3883,13 @@ public final class ActiveServices {


        final ProcessServiceRecord psr = app.mServices;
        final ProcessServiceRecord psr = app.mServices;
        final boolean newService = psr.startService(r);
        final boolean newService = psr.startService(r);
        bumpServiceExecutingLocked(r, execInFg, "create");
        bumpServiceExecutingLocked(r, execInFg, "create", null /* oomAdjReason */);
        mAm.updateLruProcessLocked(app, false, null);
        mAm.updateLruProcessLocked(app, false, null);
        updateServiceForegroundLocked(psr, /* oomAdj= */ false);
        updateServiceForegroundLocked(psr, /* oomAdj= */ false);
        if (enqueueOomAdj) {
        // Force an immediate oomAdjUpdate, so the client app could be in the correct process state
        // before doing any service related transactions
        mAm.enqueueOomAdjTargetLocked(app);
        mAm.enqueueOomAdjTargetLocked(app);
        } else {
        mAm.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
        mAm.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
        }


        boolean created = false;
        boolean created = false;
        try {
        try {
@@ -3895,7 +3910,6 @@ public final class ActiveServices {
            mAm.mBatteryStatsService.noteServiceStartLaunch(uid, packageName, serviceName);
            mAm.mBatteryStatsService.noteServiceStartLaunch(uid, packageName, serviceName);
            mAm.notifyPackageUse(r.serviceInfo.packageName,
            mAm.notifyPackageUse(r.serviceInfo.packageName,
                                 PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
                                 PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
            app.mState.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
            thread.scheduleCreateService(r, r.serviceInfo,
            thread.scheduleCreateService(r, r.serviceInfo,
                    mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
                    mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
                    app.mState.getReportedProcState());
                    app.mState.getReportedProcState());
@@ -3995,11 +4009,7 @@ public final class ActiveServices {
            mAm.grantImplicitAccess(r.userId, si.intent, si.callingId,
            mAm.grantImplicitAccess(r.userId, si.intent, si.callingId,
                    UserHandle.getAppId(r.appInfo.uid)
                    UserHandle.getAppId(r.appInfo.uid)
            );
            );
            bumpServiceExecutingLocked(r, execInFg, "start");
            bumpServiceExecutingLocked(r, execInFg, "start", null /* oomAdjReason */);
            if (!oomAdjusted) {
                oomAdjusted = true;
                mAm.updateOomAdjLocked(r.app, OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
            }
            if (r.fgRequired && !r.fgWaiting) {
            if (r.fgRequired && !r.fgWaiting) {
                if (!r.isForeground) {
                if (!r.isForeground) {
                    if (DEBUG_BACKGROUND_CHECK) {
                    if (DEBUG_BACKGROUND_CHECK) {
@@ -4023,6 +4033,10 @@ public final class ActiveServices {
            args.add(new ServiceStartArgs(si.taskRemoved, si.id, flags, si.intent));
            args.add(new ServiceStartArgs(si.taskRemoved, si.id, flags, si.intent));
        }
        }


        if (!oomAdjusted) {
            mAm.enqueueOomAdjTargetLocked(r.app);
            mAm.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_START_SERVICE);
        }
        ParceledListSlice<ServiceStartArgs> slice = new ParceledListSlice<>(args);
        ParceledListSlice<ServiceStartArgs> slice = new ParceledListSlice<>(args);
        slice.setInlineCountLimit(4);
        slice.setInlineCountLimit(4);
        Exception caughtException = null;
        Exception caughtException = null;
@@ -4117,7 +4131,7 @@ public final class ActiveServices {
            }
            }
        }
        }


        boolean needOomAdj = false;
        boolean oomAdjusted = false;
        // Tell the service that it has been unbound.
        // Tell the service that it has been unbound.
        if (r.app != null && r.app.getThread() != null) {
        if (r.app != null && r.app.getThread() != null) {
            for (int i = r.bindings.size() - 1; i >= 0; i--) {
            for (int i = r.bindings.size() - 1; i >= 0; i--) {
@@ -4126,8 +4140,8 @@ public final class ActiveServices {
                        + ": hasBound=" + ibr.hasBound);
                        + ": hasBound=" + ibr.hasBound);
                if (ibr.hasBound) {
                if (ibr.hasBound) {
                    try {
                    try {
                        bumpServiceExecutingLocked(r, false, "bring down unbind");
                        oomAdjusted |= bumpServiceExecutingLocked(r, false, "bring down unbind",
                        needOomAdj = true;
                                OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
                        ibr.hasBound = false;
                        ibr.hasBound = false;
                        ibr.requested = false;
                        ibr.requested = false;
                        r.app.getThread().scheduleUnbindService(r,
                        r.app.getThread().scheduleUnbindService(r,
@@ -4135,7 +4149,6 @@ public final class ActiveServices {
                    } catch (Exception e) {
                    } catch (Exception e) {
                        Slog.w(TAG, "Exception when unbinding service "
                        Slog.w(TAG, "Exception when unbinding service "
                                + r.shortInstanceName, e);
                                + r.shortInstanceName, e);
                        needOomAdj = false;
                        serviceProcessGoneLocked(r, enqueueOomAdj);
                        serviceProcessGoneLocked(r, enqueueOomAdj);
                        break;
                        break;
                    }
                    }
@@ -4247,10 +4260,10 @@ public final class ActiveServices {
                mAm.updateLruProcessLocked(r.app, false, null);
                mAm.updateLruProcessLocked(r.app, false, null);
                updateServiceForegroundLocked(r.app.mServices, false);
                updateServiceForegroundLocked(r.app.mServices, false);
                try {
                try {
                    bumpServiceExecutingLocked(r, false, "destroy");
                    oomAdjusted |= bumpServiceExecutingLocked(r, false, "destroy",
                            oomAdjusted ? null : OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
                    mDestroyingServices.add(r);
                    mDestroyingServices.add(r);
                    r.destroying = true;
                    r.destroying = true;
                    needOomAdj = true;
                    r.app.getThread().scheduleStopService(r);
                    r.app.getThread().scheduleStopService(r);
                } catch (Exception e) {
                } catch (Exception e) {
                    Slog.w(TAG, "Exception when destroying service "
                    Slog.w(TAG, "Exception when destroying service "
@@ -4266,11 +4279,10 @@ public final class ActiveServices {
                TAG_SERVICE, "Removed service that is not running: " + r);
                TAG_SERVICE, "Removed service that is not running: " + r);
        }
        }


        if (needOomAdj) {
        if (!oomAdjusted) {
            if (enqueueOomAdj) {
            mAm.enqueueOomAdjTargetLocked(r.app);
            mAm.enqueueOomAdjTargetLocked(r.app);
            } else {
            if (!enqueueOomAdj) {
                mAm.updateOomAdjLocked(r.app, OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
                mAm.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
            }
            }
        }
        }
        if (r.bindings.size() > 0) {
        if (r.bindings.size() > 0) {
@@ -4387,7 +4399,8 @@ public final class ActiveServices {
            if (s.app != null && s.app.getThread() != null && b.intent.apps.size() == 0
            if (s.app != null && s.app.getThread() != null && b.intent.apps.size() == 0
                    && b.intent.hasBound) {
                    && b.intent.hasBound) {
                try {
                try {
                    bumpServiceExecutingLocked(s, false, "unbind");
                    bumpServiceExecutingLocked(s, false, "unbind",
                            OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
                    if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0
                    if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0
                            && s.app.mState.getSetProcState() <= PROCESS_STATE_HEAVY_WEIGHT) {
                            && s.app.mState.getSetProcState() <= PROCESS_STATE_HEAVY_WEIGHT) {
                        // If this service's process is not already in the cached list,
                        // If this service's process is not already in the cached list,
@@ -4395,11 +4408,6 @@ public final class ActiveServices {
                        // it to go down there and we want it to start out near the top.
                        // it to go down there and we want it to start out near the top.
                        mAm.updateLruProcessLocked(s.app, false, null);
                        mAm.updateLruProcessLocked(s.app, false, null);
                    }
                    }
                    if (enqueueOomAdj) {
                        mAm.enqueueOomAdjTargetLocked(s.app);
                    } else {
                        mAm.updateOomAdjLocked(s.app, OomAdjuster.OOM_ADJ_REASON_UNBIND_SERVICE);
                    }
                    b.intent.hasBound = false;
                    b.intent.hasBound = false;
                    // Assume the client doesn't want to know about a rebind;
                    // Assume the client doesn't want to know about a rebind;
                    // we will deal with that later if it asks for one.
                    // we will deal with that later if it asks for one.