summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Dianne Hackborn <hackbod@google.com> 2012-08-13 17:14:03 -0700
committer Android (Google) Code Review <android-gerrit@google.com> 2012-08-13 17:14:04 -0700
commit87c42b9978bde888c3fd2d94e9d52256e56c3187 (patch)
tree9902a92914c19b3309174ea2b4f657eff4177dca
parent806d53c3db6588920e3d704b184c9b7e9474338d (diff)
parentf88dd0b32ea2042eb2011170be465259a21d2563 (diff)
Merge "Small service cleanup." into jb-mr1-dev
-rw-r--r--services/java/com/android/server/am/ActiveServices.java242
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java6
-rw-r--r--services/java/com/android/server/am/ProviderMap.java3
3 files changed, 114 insertions, 137 deletions
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index 533c2cd7af8c..632c2f29f98f 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -226,7 +226,7 @@ public class ActiveServices {
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType,
- callingPid, callingUid, UserId.getUserId(callingUid));
+ callingPid, callingUid, UserId.getUserId(callingUid), true);
if (res == null) {
return null;
}
@@ -277,8 +277,10 @@ public class ActiveServices {
}
// If this service is active, make sure it is stopped.
- ServiceLookupResult r = findServiceLocked(service, resolvedType,
- callerApp == null ? UserId.getCallingUserId() : callerApp.userId);
+ ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
+ Binder.getCallingPid(), Binder.getCallingUid(),
+ callerApp == null ? UserId.getCallingUserId() : callerApp.userId,
+ false);
if (r != null) {
if (r.record != null) {
final long origId = Binder.clearCallingIdentity();
@@ -296,8 +298,9 @@ public class ActiveServices {
}
IBinder peekServiceLocked(Intent service, String resolvedType) {
- ServiceLookupResult r = findServiceLocked(service, resolvedType,
- UserId.getCallingUserId());
+ ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
+ Binder.getCallingPid(), Binder.getCallingUid(),
+ UserId.getCallingUserId(), false);
IBinder ret = null;
if (r != null) {
@@ -471,7 +474,7 @@ public class ActiveServices {
ServiceLookupResult res =
retrieveServiceLocked(service, resolvedType,
- Binder.getCallingPid(), Binder.getCallingUid(), userId);
+ Binder.getCallingPid(), Binder.getCallingUid(), userId, true);
if (res == null) {
return 0;
}
@@ -482,7 +485,7 @@ public class ActiveServices {
res.record.serviceInfo.name, res.record.serviceInfo.flags)) {
userId = 0;
res = retrieveServiceLocked(service, resolvedType, Binder.getCallingPid(),
- Binder.getCallingUid(), 0);
+ Binder.getCallingUid(), 0, true);
}
ServiceRecord s = res.record;
@@ -689,60 +692,6 @@ public class ActiveServices {
record = _record;
permission = _permission;
}
- };
-
- private ServiceLookupResult findServiceLocked(Intent service,
- String resolvedType, int userId) {
- ServiceRecord r = null;
- if (service.getComponent() != null) {
- r = mServiceMap.getServiceByName(service.getComponent(), userId);
- }
- if (r == null) {
- Intent.FilterComparison filter = new Intent.FilterComparison(service);
- r = mServiceMap.getServiceByIntent(filter, userId);
- }
-
- if (r == null) {
- try {
- ResolveInfo rInfo =
- AppGlobals.getPackageManager().resolveService(
- service, resolvedType, 0, userId);
- ServiceInfo sInfo =
- rInfo != null ? rInfo.serviceInfo : null;
- if (sInfo == null) {
- return null;
- }
-
- ComponentName name = new ComponentName(
- sInfo.applicationInfo.packageName, sInfo.name);
- r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
- } catch (RemoteException ex) {
- // pm is in same process, this will never happen.
- }
- }
- if (r != null) {
- int callingPid = Binder.getCallingPid();
- int callingUid = Binder.getCallingUid();
- if (mAm.checkComponentPermission(r.permission,
- callingPid, callingUid, r.appInfo.uid, r.exported)
- != PackageManager.PERMISSION_GRANTED) {
- if (!r.exported) {
- Slog.w(TAG, "Permission Denial: Accessing service " + r.name
- + " from pid=" + callingPid
- + ", uid=" + callingUid
- + " that is not exported from uid " + r.appInfo.uid);
- return new ServiceLookupResult(null, "not exported from uid "
- + r.appInfo.uid);
- }
- Slog.w(TAG, "Permission Denial: Accessing service " + r.name
- + " from pid=" + callingPid
- + ", uid=" + callingUid
- + " requires " + r.permission);
- return new ServiceLookupResult(null, r.permission);
- }
- return new ServiceLookupResult(r, null);
- }
- return null;
}
private class ServiceRestarter implements Runnable {
@@ -760,7 +709,8 @@ public class ActiveServices {
}
private ServiceLookupResult retrieveServiceLocked(Intent service,
- String resolvedType, int callingPid, int callingUid, int userId) {
+ String resolvedType, int callingPid, int callingUid, int userId,
+ boolean createIfNeeded) {
ServiceRecord r = null;
if (DEBUG_SERVICE) Slog.v(TAG, "retrieveServiceLocked: " + service
+ " type=" + resolvedType + " callingUid=" + callingUid);
@@ -796,7 +746,7 @@ public class ActiveServices {
sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
}
r = mServiceMap.getServiceByName(name, userId);
- if (r == null) {
+ if (r == null && createIfNeeded) {
Intent.FilterComparison filter = new Intent.FilterComparison(
service.cloneFilter());
ServiceRestarter res = new ServiceRestarter();
@@ -897,87 +847,94 @@ public class ActiveServices {
boolean canceled = false;
final long now = SystemClock.uptimeMillis();
- long minDuration = SERVICE_RESTART_DURATION;
- long resetTime = SERVICE_RESET_RUN_DURATION;
if ((r.serviceInfo.applicationInfo.flags
- &ApplicationInfo.FLAG_PERSISTENT) != 0) {
- minDuration /= 4;
- }
-
- // Any delivered but not yet finished starts should be put back
- // on the pending list.
- final int N = r.deliveredStarts.size();
- if (N > 0) {
- for (int i=N-1; i>=0; i--) {
- ServiceRecord.StartItem si = r.deliveredStarts.get(i);
- si.removeUriPermissionsLocked();
- if (si.intent == null) {
- // We'll generate this again if needed.
- } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
- && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
- r.pendingStarts.add(0, si);
- long dur = SystemClock.uptimeMillis() - si.deliveredTime;
- dur *= 2;
- if (minDuration < dur) minDuration = dur;
- if (resetTime < dur) resetTime = dur;
- } else {
- Slog.w(TAG, "Canceling start item " + si.intent + " in service "
- + r.name);
- canceled = true;
+ &ApplicationInfo.FLAG_PERSISTENT) == 0) {
+ long minDuration = SERVICE_RESTART_DURATION;
+ long resetTime = SERVICE_RESET_RUN_DURATION;
+
+ // Any delivered but not yet finished starts should be put back
+ // on the pending list.
+ final int N = r.deliveredStarts.size();
+ if (N > 0) {
+ for (int i=N-1; i>=0; i--) {
+ ServiceRecord.StartItem si = r.deliveredStarts.get(i);
+ si.removeUriPermissionsLocked();
+ if (si.intent == null) {
+ // We'll generate this again if needed.
+ } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
+ && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
+ r.pendingStarts.add(0, si);
+ long dur = SystemClock.uptimeMillis() - si.deliveredTime;
+ dur *= 2;
+ if (minDuration < dur) minDuration = dur;
+ if (resetTime < dur) resetTime = dur;
+ } else {
+ Slog.w(TAG, "Canceling start item " + si.intent + " in service "
+ + r.name);
+ canceled = true;
+ }
}
+ r.deliveredStarts.clear();
}
- r.deliveredStarts.clear();
- }
- r.totalRestartCount++;
- if (r.restartDelay == 0) {
- r.restartCount++;
- r.restartDelay = minDuration;
- } else {
- // If it has been a "reasonably long time" since the service
- // was started, then reset our restart duration back to
- // the beginning, so we don't infinitely increase the duration
- // on a service that just occasionally gets killed (which is
- // a normal case, due to process being killed to reclaim memory).
- if (now > (r.restartTime+resetTime)) {
- r.restartCount = 1;
+ r.totalRestartCount++;
+ if (r.restartDelay == 0) {
+ r.restartCount++;
r.restartDelay = minDuration;
} else {
- if ((r.serviceInfo.applicationInfo.flags
- &ApplicationInfo.FLAG_PERSISTENT) != 0) {
- // Services in peristent processes will restart much more
- // quickly, since they are pretty important. (Think SystemUI).
- r.restartDelay += minDuration/2;
+ // If it has been a "reasonably long time" since the service
+ // was started, then reset our restart duration back to
+ // the beginning, so we don't infinitely increase the duration
+ // on a service that just occasionally gets killed (which is
+ // a normal case, due to process being killed to reclaim memory).
+ if (now > (r.restartTime+resetTime)) {
+ r.restartCount = 1;
+ r.restartDelay = minDuration;
} else {
- r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
- if (r.restartDelay < minDuration) {
- r.restartDelay = minDuration;
+ if ((r.serviceInfo.applicationInfo.flags
+ &ApplicationInfo.FLAG_PERSISTENT) != 0) {
+ // Services in peristent processes will restart much more
+ // quickly, since they are pretty important. (Think SystemUI).
+ r.restartDelay += minDuration/2;
+ } else {
+ r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
+ if (r.restartDelay < minDuration) {
+ r.restartDelay = minDuration;
+ }
}
}
}
- }
- r.nextRestartTime = now + r.restartDelay;
+ r.nextRestartTime = now + r.restartDelay;
- // Make sure that we don't end up restarting a bunch of services
- // all at the same time.
- boolean repeat;
- do {
- repeat = false;
- for (int i=mRestartingServices.size()-1; i>=0; i--) {
- ServiceRecord r2 = mRestartingServices.get(i);
- if (r2 != r && r.nextRestartTime
- >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
- && r.nextRestartTime
- < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
- r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
- r.restartDelay = r.nextRestartTime - now;
- repeat = true;
- break;
+ // Make sure that we don't end up restarting a bunch of services
+ // all at the same time.
+ boolean repeat;
+ do {
+ repeat = false;
+ for (int i=mRestartingServices.size()-1; i>=0; i--) {
+ ServiceRecord r2 = mRestartingServices.get(i);
+ if (r2 != r && r.nextRestartTime
+ >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
+ && r.nextRestartTime
+ < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
+ r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
+ r.restartDelay = r.nextRestartTime - now;
+ repeat = true;
+ break;
+ }
}
- }
- } while (repeat);
+ } while (repeat);
+
+ } else {
+ // Persistent processes are immediately restrted, so there is no
+ // reason to hold of on restarting their services.
+ r.totalRestartCount++;
+ r.restartCount = 0;
+ r.restartDelay = 0;
+ r.nextRestartTime = now;
+ }
if (!mRestartingServices.contains(r)) {
mRestartingServices.add(r);
@@ -1494,6 +1451,7 @@ public class ActiveServices {
boolean attachApplicationLocked(ProcessRecord proc, String processName) throws Exception {
boolean didSomething = false;
+ // Collect any services that are waiting for this process to come up.
if (mPendingServices.size() > 0) {
ServiceRecord sr = null;
try {
@@ -1515,6 +1473,22 @@ public class ActiveServices {
throw e;
}
}
+ // Also, if there are any services that are waiting to restart and
+ // would run in this process, now is a good time to start them. It would
+ // be weird to bring up the process but arbitrarily not let the services
+ // run at this point just because their restart time hasn't come up.
+ if (mRestartingServices.size() > 0) {
+ ServiceRecord sr = null;
+ for (int i=0; i<mRestartingServices.size(); i++) {
+ sr = mRestartingServices.get(i);
+ if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
+ || !processName.equals(sr.processName))) {
+ continue;
+ }
+ mAm.mHandler.removeCallbacks(sr.restarter);
+ mAm.mHandler.post(sr.restarter);
+ }
+ }
return didSomething;
}
@@ -1836,7 +1810,8 @@ public class ActiveServices {
pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
try {
List<UserInfo> users = mAm.getUserManager().getUsers();
- for (UserInfo user : users) {
+ for (int ui=0; ui<users.size(); ui++) {
+ final UserInfo user = users.get(ui);
if (mServiceMap.getAllServices(user.id).size() > 0) {
boolean printed = false;
long nowReal = SystemClock.elapsedRealtime();
@@ -1852,7 +1827,10 @@ public class ActiveServices {
continue;
}
if (!printed) {
- pw.println(" Active services:");
+ if (ui > 0) {
+ pw.println();
+ }
+ pw.println(" User " + user.id + " active services:");
printed = true;
}
if (needSep) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d3ec9f7b8b3d..f2420785f857 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1952,7 +1952,7 @@ public final class ActivityManagerService extends ActivityManagerNative
mPidsSelfLocked.remove(app.pid);
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
}
- app.pid = 0;
+ app.setPid(0);
}
if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
@@ -2055,7 +2055,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
buf.append("}");
Slog.i(TAG, buf.toString());
- app.pid = startResult.pid;
+ app.setPid(startResult.pid);
app.usingWrapper = startResult.usingWrapper;
app.removed = false;
synchronized (mPidsSelfLocked) {
@@ -2067,7 +2067,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
} catch (RuntimeException e) {
// XXX do better error recovery.
- app.pid = 0;
+ app.setPid(0);
Slog.e(TAG, "Failure starting process " + app.processName, e);
}
}
diff --git a/services/java/com/android/server/am/ProviderMap.java b/services/java/com/android/server/am/ProviderMap.java
index f4d0f9b95924..405718f492c2 100644
--- a/services/java/com/android/server/am/ProviderMap.java
+++ b/services/java/com/android/server/am/ProviderMap.java
@@ -198,7 +198,6 @@ public class ProviderMap {
void dumpProvidersLocked(PrintWriter pw, boolean dumpAll) {
if (mSingletonByClass.size() > 0) {
- pw.println("");
pw.println(" Published single-user content providers (by class):");
dumpProvidersByClassLocked(pw, dumpAll, mSingletonByClass);
}
@@ -206,10 +205,10 @@ public class ProviderMap {
pw.println("");
for (int i = 0; i < mProvidersByClassPerUser.size(); i++) {
HashMap<ComponentName, ContentProviderRecord> map = mProvidersByClassPerUser.valueAt(i);
+ pw.println("");
pw.println(" Published user " + mProvidersByClassPerUser.keyAt(i)
+ " content providers (by class):");
dumpProvidersByClassLocked(pw, dumpAll, map);
- pw.println(" ");
}
if (dumpAll) {