if (callerApp == null) {
throw new SecurityException(
"Unable to find app for caller " + caller
- + " (pid=" + Binder.getCallingPid()
+ + " (pid=" + callingPid
+ ") when starting service " + service);
}
callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
// If this isn't a direct-to-foreground start, check our ability to kick off an
// arbitrary service
if (!r.startRequested && !fgRequired) {
- final long token = Binder.clearCallingIdentity();
- try {
- // Before going further -- if this app is not allowed to start services in the
- // background, then at this point we aren't going to let it period.
- final int allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName,
- r.appInfo.targetSdkVersion, callingPid, false, false);
- if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
- Slog.w(TAG, "Background start not allowed: service "
- + service + " to " + r.name.flattenToShortString()
- + " from pid=" + callingPid + " uid=" + callingUid
- + " pkg=" + callingPackage);
- if (allowed == ActivityManager.APP_START_MODE_DELAYED) {
- // In this case we are silently disabling the app, to disrupt as
- // little as possible existing apps.
- return null;
- }
- // This app knows it is in the new model where this operation is not
- // allowed, so tell it what has happened.
- UidRecord uidRec = mAm.mActiveUids.get(r.appInfo.uid);
- return new ComponentName("?", "app is in background uid " + uidRec);
- }
- } finally {
- Binder.restoreCallingIdentity(token);
+ // Before going further -- if this app is not allowed to start services in the
+ // background, then at this point we aren't going to let it period.
+ final int allowed = mAm.getAppStartModeLocked(r.appInfo.uid, r.packageName,
+ r.appInfo.targetSdkVersion, callingPid, false, false);
+ if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
+ Slog.w(TAG, "Background start not allowed: service "
+ + service + " to " + r.name.flattenToShortString()
+ + " from pid=" + callingPid + " uid=" + callingUid
+ + " pkg=" + callingPackage);
+ if (allowed == ActivityManager.APP_START_MODE_DELAYED) {
+ // In this case we are silently disabling the app, to disrupt as
+ // little as possible existing apps.
+ return null;
+ }
+ // This app knows it is in the new model where this operation is not
+ // allowed, so tell it what has happened.
+ UidRecord uidRec = mAm.mActiveUids.get(r.appInfo.uid);
+ return new ComponentName("?", "app is in background uid " + uidRec);
}
}
}
private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
- IBinder threadBinder = thread.asBinder();
+ final IBinder threadBinder = thread.asBinder();
// Find the application record.
for (int i=mLruProcesses.size()-1; i>=0; i--) {
- ProcessRecord rec = mLruProcesses.get(i);
+ final ProcessRecord rec = mLruProcesses.get(i);
if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
return i;
}
}
int appIndex = getLRURecordIndexForAppLocked(thread);
- return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
+ if (appIndex >= 0) {
+ return mLruProcesses.get(appIndex);
+ }
+
+ // Validation: if it isn't in the LRU list, it shouldn't exist, but let's
+ // double-check that.
+ final IBinder threadBinder = thread.asBinder();
+ final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
+ for (int i = pmap.size()-1; i >= 0; i--) {
+ final SparseArray<ProcessRecord> procs = pmap.valueAt(i);
+ for (int j = procs.size()-1; j >= 0; j--) {
+ final ProcessRecord proc = procs.valueAt(j);
+ if (proc.thread != null && proc.thread.asBinder() == threadBinder) {
+ Slog.wtf(TAG, "getRecordForApp: exists in name list but not in LRU list: "
+ + proc);
+ return proc;
+ }
+ }
+ }
+
+ return null;
}
final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
- ComponentName res = mServices.startServiceLocked(caller, service,
- resolvedType, id, notification, callingPid, callingUid,
- requireForeground, callingPackage, userId);
- Binder.restoreCallingIdentity(origId);
+ ComponentName res;
+ try {
+ res = mServices.startServiceLocked(caller, service,
+ resolvedType, id, notification, callingPid, callingUid,
+ requireForeground, callingPackage, userId);
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
return res;
}
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"startServiceInPackage: " + service + " type=" + resolvedType);
final long origId = Binder.clearCallingIdentity();
- ComponentName res = mServices.startServiceLocked(null, service,
- resolvedType, 0, null, -1, uid, fgRequired, callingPackage, userId);
- Binder.restoreCallingIdentity(origId);
+ ComponentName res;
+ try {
+ res = mServices.startServiceLocked(null, service,
+ resolvedType, 0, null, -1, uid, fgRequired, callingPackage, userId);
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
return res;
}
}