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
This commit is contained in:
Jing Ji
2021-07-15 14:03:26 -07:00
parent 5b1b2b1555
commit eb3c49a84e

View File

@@ -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.