Skip to content

Commit f88dd0b

Browse files
author
Dianne Hackborn
committed
Small service cleanup.
Get rid of duplication between find/retrieve service funcs; when a service in a persistent process crashes, restart it immediately since the persistent process is going to be immediately restarted anyway; when a new process is attaching, immediately restart any services associated with it that are waiting to restart, since it is weird to not let them run if the process comes back for some other reason. Change-Id: Id087fe04ebf2b6a4bd00732796c8326364765ea7
1 parent ee8655c commit f88dd0b

File tree

3 files changed

+114
-137
lines changed

3 files changed

+114
-137
lines changed

services/java/com/android/server/am/ActiveServices.java

Lines changed: 110 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ ComponentName startServiceLocked(IApplicationThread caller,
226226

227227
ServiceLookupResult res =
228228
retrieveServiceLocked(service, resolvedType,
229-
callingPid, callingUid, UserId.getUserId(callingUid));
229+
callingPid, callingUid, UserId.getUserId(callingUid), true);
230230
if (res == null) {
231231
return null;
232232
}
@@ -277,8 +277,10 @@ int stopServiceLocked(IApplicationThread caller, Intent service,
277277
}
278278

279279
// If this service is active, make sure it is stopped.
280-
ServiceLookupResult r = findServiceLocked(service, resolvedType,
281-
callerApp == null ? UserId.getCallingUserId() : callerApp.userId);
280+
ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
281+
Binder.getCallingPid(), Binder.getCallingUid(),
282+
callerApp == null ? UserId.getCallingUserId() : callerApp.userId,
283+
false);
282284
if (r != null) {
283285
if (r.record != null) {
284286
final long origId = Binder.clearCallingIdentity();
@@ -296,8 +298,9 @@ int stopServiceLocked(IApplicationThread caller, Intent service,
296298
}
297299

298300
IBinder peekServiceLocked(Intent service, String resolvedType) {
299-
ServiceLookupResult r = findServiceLocked(service, resolvedType,
300-
UserId.getCallingUserId());
301+
ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
302+
Binder.getCallingPid(), Binder.getCallingUid(),
303+
UserId.getCallingUserId(), false);
301304

302305
IBinder ret = null;
303306
if (r != null) {
@@ -471,7 +474,7 @@ int bindServiceLocked(IApplicationThread caller, IBinder token,
471474

472475
ServiceLookupResult res =
473476
retrieveServiceLocked(service, resolvedType,
474-
Binder.getCallingPid(), Binder.getCallingUid(), userId);
477+
Binder.getCallingPid(), Binder.getCallingUid(), userId, true);
475478
if (res == null) {
476479
return 0;
477480
}
@@ -482,7 +485,7 @@ int bindServiceLocked(IApplicationThread caller, IBinder token,
482485
res.record.serviceInfo.name, res.record.serviceInfo.flags)) {
483486
userId = 0;
484487
res = retrieveServiceLocked(service, resolvedType, Binder.getCallingPid(),
485-
Binder.getCallingUid(), 0);
488+
Binder.getCallingUid(), 0, true);
486489
}
487490
ServiceRecord s = res.record;
488491

@@ -689,60 +692,6 @@ private final class ServiceLookupResult {
689692
record = _record;
690693
permission = _permission;
691694
}
692-
};
693-
694-
private ServiceLookupResult findServiceLocked(Intent service,
695-
String resolvedType, int userId) {
696-
ServiceRecord r = null;
697-
if (service.getComponent() != null) {
698-
r = mServiceMap.getServiceByName(service.getComponent(), userId);
699-
}
700-
if (r == null) {
701-
Intent.FilterComparison filter = new Intent.FilterComparison(service);
702-
r = mServiceMap.getServiceByIntent(filter, userId);
703-
}
704-
705-
if (r == null) {
706-
try {
707-
ResolveInfo rInfo =
708-
AppGlobals.getPackageManager().resolveService(
709-
service, resolvedType, 0, userId);
710-
ServiceInfo sInfo =
711-
rInfo != null ? rInfo.serviceInfo : null;
712-
if (sInfo == null) {
713-
return null;
714-
}
715-
716-
ComponentName name = new ComponentName(
717-
sInfo.applicationInfo.packageName, sInfo.name);
718-
r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
719-
} catch (RemoteException ex) {
720-
// pm is in same process, this will never happen.
721-
}
722-
}
723-
if (r != null) {
724-
int callingPid = Binder.getCallingPid();
725-
int callingUid = Binder.getCallingUid();
726-
if (mAm.checkComponentPermission(r.permission,
727-
callingPid, callingUid, r.appInfo.uid, r.exported)
728-
!= PackageManager.PERMISSION_GRANTED) {
729-
if (!r.exported) {
730-
Slog.w(TAG, "Permission Denial: Accessing service " + r.name
731-
+ " from pid=" + callingPid
732-
+ ", uid=" + callingUid
733-
+ " that is not exported from uid " + r.appInfo.uid);
734-
return new ServiceLookupResult(null, "not exported from uid "
735-
+ r.appInfo.uid);
736-
}
737-
Slog.w(TAG, "Permission Denial: Accessing service " + r.name
738-
+ " from pid=" + callingPid
739-
+ ", uid=" + callingUid
740-
+ " requires " + r.permission);
741-
return new ServiceLookupResult(null, r.permission);
742-
}
743-
return new ServiceLookupResult(r, null);
744-
}
745-
return null;
746695
}
747696

748697
private class ServiceRestarter implements Runnable {
@@ -760,7 +709,8 @@ public void run() {
760709
}
761710

762711
private ServiceLookupResult retrieveServiceLocked(Intent service,
763-
String resolvedType, int callingPid, int callingUid, int userId) {
712+
String resolvedType, int callingPid, int callingUid, int userId,
713+
boolean createIfNeeded) {
764714
ServiceRecord r = null;
765715
if (DEBUG_SERVICE) Slog.v(TAG, "retrieveServiceLocked: " + service
766716
+ " type=" + resolvedType + " callingUid=" + callingUid);
@@ -796,7 +746,7 @@ private ServiceLookupResult retrieveServiceLocked(Intent service,
796746
sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
797747
}
798748
r = mServiceMap.getServiceByName(name, userId);
799-
if (r == null) {
749+
if (r == null && createIfNeeded) {
800750
Intent.FilterComparison filter = new Intent.FilterComparison(
801751
service.cloneFilter());
802752
ServiceRestarter res = new ServiceRestarter();
@@ -897,87 +847,94 @@ private final boolean scheduleServiceRestartLocked(ServiceRecord r,
897847
boolean canceled = false;
898848

899849
final long now = SystemClock.uptimeMillis();
900-
long minDuration = SERVICE_RESTART_DURATION;
901-
long resetTime = SERVICE_RESET_RUN_DURATION;
902850

903851
if ((r.serviceInfo.applicationInfo.flags
904-
&ApplicationInfo.FLAG_PERSISTENT) != 0) {
905-
minDuration /= 4;
906-
}
907-
908-
// Any delivered but not yet finished starts should be put back
909-
// on the pending list.
910-
final int N = r.deliveredStarts.size();
911-
if (N > 0) {
912-
for (int i=N-1; i>=0; i--) {
913-
ServiceRecord.StartItem si = r.deliveredStarts.get(i);
914-
si.removeUriPermissionsLocked();
915-
if (si.intent == null) {
916-
// We'll generate this again if needed.
917-
} else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
918-
&& si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
919-
r.pendingStarts.add(0, si);
920-
long dur = SystemClock.uptimeMillis() - si.deliveredTime;
921-
dur *= 2;
922-
if (minDuration < dur) minDuration = dur;
923-
if (resetTime < dur) resetTime = dur;
924-
} else {
925-
Slog.w(TAG, "Canceling start item " + si.intent + " in service "
926-
+ r.name);
927-
canceled = true;
852+
&ApplicationInfo.FLAG_PERSISTENT) == 0) {
853+
long minDuration = SERVICE_RESTART_DURATION;
854+
long resetTime = SERVICE_RESET_RUN_DURATION;
855+
856+
// Any delivered but not yet finished starts should be put back
857+
// on the pending list.
858+
final int N = r.deliveredStarts.size();
859+
if (N > 0) {
860+
for (int i=N-1; i>=0; i--) {
861+
ServiceRecord.StartItem si = r.deliveredStarts.get(i);
862+
si.removeUriPermissionsLocked();
863+
if (si.intent == null) {
864+
// We'll generate this again if needed.
865+
} else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
866+
&& si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
867+
r.pendingStarts.add(0, si);
868+
long dur = SystemClock.uptimeMillis() - si.deliveredTime;
869+
dur *= 2;
870+
if (minDuration < dur) minDuration = dur;
871+
if (resetTime < dur) resetTime = dur;
872+
} else {
873+
Slog.w(TAG, "Canceling start item " + si.intent + " in service "
874+
+ r.name);
875+
canceled = true;
876+
}
928877
}
878+
r.deliveredStarts.clear();
929879
}
930-
r.deliveredStarts.clear();
931-
}
932880

933-
r.totalRestartCount++;
934-
if (r.restartDelay == 0) {
935-
r.restartCount++;
936-
r.restartDelay = minDuration;
937-
} else {
938-
// If it has been a "reasonably long time" since the service
939-
// was started, then reset our restart duration back to
940-
// the beginning, so we don't infinitely increase the duration
941-
// on a service that just occasionally gets killed (which is
942-
// a normal case, due to process being killed to reclaim memory).
943-
if (now > (r.restartTime+resetTime)) {
944-
r.restartCount = 1;
881+
r.totalRestartCount++;
882+
if (r.restartDelay == 0) {
883+
r.restartCount++;
945884
r.restartDelay = minDuration;
946885
} else {
947-
if ((r.serviceInfo.applicationInfo.flags
948-
&ApplicationInfo.FLAG_PERSISTENT) != 0) {
949-
// Services in peristent processes will restart much more
950-
// quickly, since they are pretty important. (Think SystemUI).
951-
r.restartDelay += minDuration/2;
886+
// If it has been a "reasonably long time" since the service
887+
// was started, then reset our restart duration back to
888+
// the beginning, so we don't infinitely increase the duration
889+
// on a service that just occasionally gets killed (which is
890+
// a normal case, due to process being killed to reclaim memory).
891+
if (now > (r.restartTime+resetTime)) {
892+
r.restartCount = 1;
893+
r.restartDelay = minDuration;
952894
} else {
953-
r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
954-
if (r.restartDelay < minDuration) {
955-
r.restartDelay = minDuration;
895+
if ((r.serviceInfo.applicationInfo.flags
896+
&ApplicationInfo.FLAG_PERSISTENT) != 0) {
897+
// Services in peristent processes will restart much more
898+
// quickly, since they are pretty important. (Think SystemUI).
899+
r.restartDelay += minDuration/2;
900+
} else {
901+
r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
902+
if (r.restartDelay < minDuration) {
903+
r.restartDelay = minDuration;
904+
}
956905
}
957906
}
958907
}
959-
}
960908

961-
r.nextRestartTime = now + r.restartDelay;
909+
r.nextRestartTime = now + r.restartDelay;
962910

963-
// Make sure that we don't end up restarting a bunch of services
964-
// all at the same time.
965-
boolean repeat;
966-
do {
967-
repeat = false;
968-
for (int i=mRestartingServices.size()-1; i>=0; i--) {
969-
ServiceRecord r2 = mRestartingServices.get(i);
970-
if (r2 != r && r.nextRestartTime
971-
>= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
972-
&& r.nextRestartTime
973-
< (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
974-
r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
975-
r.restartDelay = r.nextRestartTime - now;
976-
repeat = true;
977-
break;
911+
// Make sure that we don't end up restarting a bunch of services
912+
// all at the same time.
913+
boolean repeat;
914+
do {
915+
repeat = false;
916+
for (int i=mRestartingServices.size()-1; i>=0; i--) {
917+
ServiceRecord r2 = mRestartingServices.get(i);
918+
if (r2 != r && r.nextRestartTime
919+
>= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
920+
&& r.nextRestartTime
921+
< (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
922+
r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
923+
r.restartDelay = r.nextRestartTime - now;
924+
repeat = true;
925+
break;
926+
}
978927
}
979-
}
980-
} while (repeat);
928+
} while (repeat);
929+
930+
} else {
931+
// Persistent processes are immediately restrted, so there is no
932+
// reason to hold of on restarting their services.
933+
r.totalRestartCount++;
934+
r.restartCount = 0;
935+
r.restartDelay = 0;
936+
r.nextRestartTime = now;
937+
}
981938

982939
if (!mRestartingServices.contains(r)) {
983940
mRestartingServices.add(r);
@@ -1494,6 +1451,7 @@ private void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
14941451

14951452
boolean attachApplicationLocked(ProcessRecord proc, String processName) throws Exception {
14961453
boolean didSomething = false;
1454+
// Collect any services that are waiting for this process to come up.
14971455
if (mPendingServices.size() > 0) {
14981456
ServiceRecord sr = null;
14991457
try {
@@ -1515,6 +1473,22 @@ boolean attachApplicationLocked(ProcessRecord proc, String processName) throws E
15151473
throw e;
15161474
}
15171475
}
1476+
// Also, if there are any services that are waiting to restart and
1477+
// would run in this process, now is a good time to start them. It would
1478+
// be weird to bring up the process but arbitrarily not let the services
1479+
// run at this point just because their restart time hasn't come up.
1480+
if (mRestartingServices.size() > 0) {
1481+
ServiceRecord sr = null;
1482+
for (int i=0; i<mRestartingServices.size(); i++) {
1483+
sr = mRestartingServices.get(i);
1484+
if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
1485+
|| !processName.equals(sr.processName))) {
1486+
continue;
1487+
}
1488+
mAm.mHandler.removeCallbacks(sr.restarter);
1489+
mAm.mHandler.post(sr.restarter);
1490+
}
1491+
}
15181492
return didSomething;
15191493
}
15201494

@@ -1836,7 +1810,8 @@ boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18361810
pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
18371811
try {
18381812
List<UserInfo> users = mAm.getUserManager().getUsers();
1839-
for (UserInfo user : users) {
1813+
for (int ui=0; ui<users.size(); ui++) {
1814+
final UserInfo user = users.get(ui);
18401815
if (mServiceMap.getAllServices(user.id).size() > 0) {
18411816
boolean printed = false;
18421817
long nowReal = SystemClock.elapsedRealtime();
@@ -1852,7 +1827,10 @@ boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
18521827
continue;
18531828
}
18541829
if (!printed) {
1855-
pw.println(" Active services:");
1830+
if (ui > 0) {
1831+
pw.println();
1832+
}
1833+
pw.println(" User " + user.id + " active services:");
18561834
printed = true;
18571835
}
18581836
if (needSep) {

services/java/com/android/server/am/ActivityManagerService.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1952,7 +1952,7 @@ private final void startProcessLocked(ProcessRecord app,
19521952
mPidsSelfLocked.remove(app.pid);
19531953
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
19541954
}
1955-
app.pid = 0;
1955+
app.setPid(0);
19561956
}
19571957

19581958
if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
@@ -2055,7 +2055,7 @@ private final void startProcessLocked(ProcessRecord app,
20552055
}
20562056
buf.append("}");
20572057
Slog.i(TAG, buf.toString());
2058-
app.pid = startResult.pid;
2058+
app.setPid(startResult.pid);
20592059
app.usingWrapper = startResult.usingWrapper;
20602060
app.removed = false;
20612061
synchronized (mPidsSelfLocked) {
@@ -2067,7 +2067,7 @@ private final void startProcessLocked(ProcessRecord app,
20672067
}
20682068
} catch (RuntimeException e) {
20692069
// XXX do better error recovery.
2070-
app.pid = 0;
2070+
app.setPid(0);
20712071
Slog.e(TAG, "Failure starting process " + app.processName, e);
20722072
}
20732073
}

services/java/com/android/server/am/ProviderMap.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,18 +198,17 @@ private void dumpProvidersByNameLocked(PrintWriter pw,
198198

199199
void dumpProvidersLocked(PrintWriter pw, boolean dumpAll) {
200200
if (mSingletonByClass.size() > 0) {
201-
pw.println("");
202201
pw.println(" Published single-user content providers (by class):");
203202
dumpProvidersByClassLocked(pw, dumpAll, mSingletonByClass);
204203
}
205204

206205
pw.println("");
207206
for (int i = 0; i < mProvidersByClassPerUser.size(); i++) {
208207
HashMap<ComponentName, ContentProviderRecord> map = mProvidersByClassPerUser.valueAt(i);
208+
pw.println("");
209209
pw.println(" Published user " + mProvidersByClassPerUser.keyAt(i)
210210
+ " content providers (by class):");
211211
dumpProvidersByClassLocked(pw, dumpAll, map);
212-
pw.println(" ");
213212
}
214213

215214
if (dumpAll) {

0 commit comments

Comments
 (0)