Merge "Work on issue #11634365: Leaking restarting services" into klp-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
596e409ec9
@ -307,7 +307,7 @@ public final class ActiveServices {
|
|||||||
ServiceRecord r = res.record;
|
ServiceRecord r = res.record;
|
||||||
NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
|
NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
|
||||||
callingUid, r.packageName, service, service.getFlags(), null);
|
callingUid, r.packageName, service, service.getFlags(), null);
|
||||||
if (unscheduleServiceRestartLocked(r, callingUid)) {
|
if (unscheduleServiceRestartLocked(r, callingUid, false)) {
|
||||||
if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
|
if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
|
||||||
}
|
}
|
||||||
r.lastActivity = SystemClock.uptimeMillis();
|
r.lastActivity = SystemClock.uptimeMillis();
|
||||||
@ -701,7 +701,7 @@ public final class ActiveServices {
|
|||||||
final long origId = Binder.clearCallingIdentity();
|
final long origId = Binder.clearCallingIdentity();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (unscheduleServiceRestartLocked(s, callerApp.info.uid)) {
|
if (unscheduleServiceRestartLocked(s, callerApp.info.uid, false)) {
|
||||||
if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
|
if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
|
||||||
+ s);
|
+ s);
|
||||||
}
|
}
|
||||||
@ -1002,14 +1002,11 @@ public final class ActiveServices {
|
|||||||
smap.mServicesByIntent.put(filter, r);
|
smap.mServicesByIntent.put(filter, r);
|
||||||
|
|
||||||
// Make sure this component isn't in the pending list.
|
// Make sure this component isn't in the pending list.
|
||||||
int N = mPendingServices.size();
|
for (int i=mPendingServices.size()-1; i>=0; i--) {
|
||||||
for (int i=0; i<N; i++) {
|
|
||||||
ServiceRecord pr = mPendingServices.get(i);
|
ServiceRecord pr = mPendingServices.get(i);
|
||||||
if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
|
if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
|
||||||
&& pr.name.equals(name)) {
|
&& pr.name.equals(name)) {
|
||||||
mPendingServices.remove(i);
|
mPendingServices.remove(i);
|
||||||
i--;
|
|
||||||
N--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1101,6 +1098,14 @@ public final class ActiveServices {
|
|||||||
boolean allowCancel) {
|
boolean allowCancel) {
|
||||||
boolean canceled = false;
|
boolean canceled = false;
|
||||||
|
|
||||||
|
ServiceMap smap = getServiceMap(r.userId);
|
||||||
|
if (smap.mServicesByName.get(r.name) != r) {
|
||||||
|
ServiceRecord cur = smap.mServicesByName.get(r.name);
|
||||||
|
Slog.wtf(TAG, "Attempting to schedule restart of " + r
|
||||||
|
+ " when found in map: " + cur);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
final long now = SystemClock.uptimeMillis();
|
final long now = SystemClock.uptimeMillis();
|
||||||
|
|
||||||
if ((r.serviceInfo.applicationInfo.flags
|
if ((r.serviceInfo.applicationInfo.flags
|
||||||
@ -1210,8 +1215,9 @@ public final class ActiveServices {
|
|||||||
bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true);
|
bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final boolean unscheduleServiceRestartLocked(ServiceRecord r, int callingUid) {
|
private final boolean unscheduleServiceRestartLocked(ServiceRecord r, int callingUid,
|
||||||
if (r.restartDelay == 0) {
|
boolean force) {
|
||||||
|
if (!force && r.restartDelay == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Remove from the restarting list; if the service is currently on the
|
// Remove from the restarting list; if the service is currently on the
|
||||||
@ -1222,12 +1228,31 @@ public final class ActiveServices {
|
|||||||
r.resetRestartCounter();
|
r.resetRestartCounter();
|
||||||
}
|
}
|
||||||
if (removed) {
|
if (removed) {
|
||||||
r.clearRestarting(mAm.mProcessStats.getMemFactorLocked(), SystemClock.uptimeMillis());
|
clearRestartingIfNeededLocked(r);
|
||||||
}
|
}
|
||||||
mAm.mHandler.removeCallbacks(r.restarter);
|
mAm.mHandler.removeCallbacks(r.restarter);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void clearRestartingIfNeededLocked(ServiceRecord r) {
|
||||||
|
if (r.restartTracker != null) {
|
||||||
|
// If this is the last restarting record with this tracker, then clear
|
||||||
|
// the tracker's restarting state.
|
||||||
|
boolean stillTracking = false;
|
||||||
|
for (int i=mRestartingServices.size()-1; i>=0; i--) {
|
||||||
|
if (mRestartingServices.get(i).restartTracker == r.restartTracker) {
|
||||||
|
stillTracking = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!stillTracking) {
|
||||||
|
r.restartTracker.setRestarting(false, mAm.mProcessStats.getMemFactorLocked(),
|
||||||
|
SystemClock.uptimeMillis());
|
||||||
|
r.restartTracker = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final String bringUpServiceLocked(ServiceRecord r,
|
private final String bringUpServiceLocked(ServiceRecord r,
|
||||||
int intentFlags, boolean execInFg, boolean whileRestarting) {
|
int intentFlags, boolean execInFg, boolean whileRestarting) {
|
||||||
//Slog.i(TAG, "Bring up service:");
|
//Slog.i(TAG, "Bring up service:");
|
||||||
@ -1248,7 +1273,7 @@ public final class ActiveServices {
|
|||||||
// We are now bringing the service up, so no longer in the
|
// We are now bringing the service up, so no longer in the
|
||||||
// restarting state.
|
// restarting state.
|
||||||
if (mRestartingServices.remove(r)) {
|
if (mRestartingServices.remove(r)) {
|
||||||
r.clearRestarting(mAm.mProcessStats.getMemFactorLocked(), SystemClock.uptimeMillis());
|
clearRestartingIfNeededLocked(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure this service is no longer considered delayed, we are starting it now.
|
// Make sure this service is no longer considered delayed, we are starting it now.
|
||||||
@ -1560,16 +1585,13 @@ public final class ActiveServices {
|
|||||||
smap.mServicesByName.remove(r.name);
|
smap.mServicesByName.remove(r.name);
|
||||||
smap.mServicesByIntent.remove(r.intent);
|
smap.mServicesByIntent.remove(r.intent);
|
||||||
r.totalRestartCount = 0;
|
r.totalRestartCount = 0;
|
||||||
unscheduleServiceRestartLocked(r, 0);
|
unscheduleServiceRestartLocked(r, 0, true);
|
||||||
|
|
||||||
// Also make sure it is not on the pending list.
|
// Also make sure it is not on the pending list.
|
||||||
int N = mPendingServices.size();
|
for (int i=mPendingServices.size()-1; i>=0; i--) {
|
||||||
for (int i=0; i<N; i++) {
|
|
||||||
if (mPendingServices.get(i) == r) {
|
if (mPendingServices.get(i) == r) {
|
||||||
mPendingServices.remove(i);
|
mPendingServices.remove(i);
|
||||||
if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
|
if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
|
||||||
i--;
|
|
||||||
N--;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2076,8 +2098,14 @@ public final class ActiveServices {
|
|||||||
if (r.processName.equals(app.processName) &&
|
if (r.processName.equals(app.processName) &&
|
||||||
r.serviceInfo.applicationInfo.uid == app.info.uid) {
|
r.serviceInfo.applicationInfo.uid == app.info.uid) {
|
||||||
mRestartingServices.remove(i);
|
mRestartingServices.remove(i);
|
||||||
r.clearRestarting(mAm.mProcessStats.getMemFactorLocked(),
|
clearRestartingIfNeededLocked(r);
|
||||||
SystemClock.uptimeMillis());
|
}
|
||||||
|
}
|
||||||
|
for (int i=mPendingServices.size()-1; i>=0; i--) {
|
||||||
|
ServiceRecord r = mPendingServices.get(i);
|
||||||
|
if (r.processName.equals(app.processName) &&
|
||||||
|
r.serviceInfo.applicationInfo.uid == app.info.uid) {
|
||||||
|
mPendingServices.remove(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -354,13 +354,6 @@ final class ServiceRecord extends Binder {
|
|||||||
restartTracker.setRestarting(true, memFactor, now);
|
restartTracker.setRestarting(true, memFactor, now);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearRestarting(int memFactor, long now) {
|
|
||||||
if (restartTracker != null) {
|
|
||||||
restartTracker.setRestarting(false, memFactor, now);
|
|
||||||
restartTracker = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public AppBindRecord retrieveAppBindingLocked(Intent intent,
|
public AppBindRecord retrieveAppBindingLocked(Intent intent,
|
||||||
ProcessRecord app) {
|
ProcessRecord app) {
|
||||||
Intent.FilterComparison filter = new Intent.FilterComparison(intent);
|
Intent.FilterComparison filter = new Intent.FilterComparison(intent);
|
||||||
|
Reference in New Issue
Block a user