diff options
| author | 2016-08-18 18:15:49 +0000 | |
|---|---|---|
| committer | 2016-08-18 18:15:50 +0000 | |
| commit | bd912314c308f305baf4ce02fbb215942cc74283 (patch) | |
| tree | 11697e2bcd663ff9d4d945fefa70b4404e3c3190 | |
| parent | b67b8a6d6cfffd13a244249be44033a2772e5af9 (diff) | |
| parent | ad51be90d8dbac8eb9a36ce07c423d24e4b0b321 (diff) | |
Merge "Work on issue #29939676: android.util.ArraySet static cache corruption"
| -rw-r--r-- | services/core/java/com/android/server/am/ActiveServices.java | 106 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/BroadcastQueue.java | 2 |
2 files changed, 41 insertions, 67 deletions
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 5f305ae1f7bb..fb4b01028e73 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -200,24 +200,24 @@ public final class ActiveServices { switch (msg.what) { case MSG_BG_START_TIMEOUT: { synchronized (mAm) { - rescheduleDelayedStarts(); + rescheduleDelayedStartsLocked(); } } break; } } - void ensureNotStartingBackground(ServiceRecord r) { + void ensureNotStartingBackgroundLocked(ServiceRecord r) { if (mStartingBackground.remove(r)) { if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "No longer background starting: " + r); - rescheduleDelayedStarts(); + rescheduleDelayedStartsLocked(); } if (mDelayedStartList.remove(r)) { if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "No longer delaying start: " + r); } } - void rescheduleDelayedStarts() { + void rescheduleDelayedStartsLocked() { removeMessages(MSG_BG_START_TIMEOUT); final long now = SystemClock.uptimeMillis(); for (int i=0, N=mStartingBackground.size(); i<N; i++) { @@ -278,19 +278,19 @@ public final class ActiveServices { ? maxBg : ActivityManager.isLowRamDeviceStatic() ? 1 : 8; } - ServiceRecord getServiceByName(ComponentName name, int callingUser) { + ServiceRecord getServiceByNameLocked(ComponentName name, int callingUser) { // TODO: Deal with global services if (DEBUG_MU) - Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser); - return getServiceMap(callingUser).mServicesByName.get(name); + Slog.v(TAG_MU, "getServiceByNameLocked(" + name + "), callingUser = " + callingUser); + return getServiceMapLocked(callingUser).mServicesByName.get(name); } - boolean hasBackgroundServices(int callingUser) { + boolean hasBackgroundServicesLocked(int callingUser) { ServiceMap smap = mServiceMap.get(callingUser); return smap != null ? smap.mStartingBackground.size() >= mMaxStartingBackground : false; } - private ServiceMap getServiceMap(int callingUser) { + private ServiceMap getServiceMapLocked(int callingUser) { ServiceMap smap = mServiceMap.get(callingUser); if (smap == null) { smap = new ServiceMap(mAm.mHandler.getLooper(), callingUser); @@ -299,8 +299,8 @@ public final class ActiveServices { return smap; } - ArrayMap<ComponentName, ServiceRecord> getServices(int callingUser) { - return getServiceMap(callingUser).mServicesByName; + ArrayMap<ComponentName, ServiceRecord> getServicesLocked(int callingUser) { + return getServiceMapLocked(callingUser).mServicesByName; } ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, @@ -384,7 +384,7 @@ public final class ActiveServices { r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(), service, neededGrants)); - final ServiceMap smap = getServiceMap(r.userId); + final ServiceMap smap = getServiceMapLocked(r.userId); boolean addToStarting = false; if (!callerFg && r.app == null && mAm.mUserController.hasStartedUserState(r.userId)) { @@ -523,10 +523,10 @@ public final class ActiveServices { Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r); } if (first) { - smap.rescheduleDelayedStarts(); + smap.rescheduleDelayedStartsLocked(); } } else if (callerFg) { - smap.ensureNotStartingBackground(r); + smap.ensureNotStartingBackgroundLocked(r); } return r.name; @@ -607,7 +607,7 @@ public final class ActiveServices { for (int i=stopping.size()-1; i>=0; i--) { ServiceRecord service = stopping.get(i); service.delayed = false; - services.ensureNotStartingBackground(service); + services.ensureNotStartingBackgroundLocked(service); stopServiceLocked(service); } } @@ -709,7 +709,7 @@ public final class ActiveServices { if (r.app != null) { updateServiceForegroundLocked(r.app, true); } - getServiceMap(r.userId).ensureNotStartingBackground(r); + getServiceMapLocked(r.userId).ensureNotStartingBackgroundLocked(r); mAm.notifyPackageUse(r.serviceInfo.packageName, PackageManager.NOTIFY_PACKAGE_USE_FOREGROUND_SERVICE); } else { @@ -744,7 +744,7 @@ public final class ActiveServices { // with the same notification ID. If so, we shouldn't actually cancel it, // because that would wipe away the notification that still needs to be shown // due the other service. - ServiceMap sm = getServiceMap(r.userId); + ServiceMap sm = getServiceMapLocked(r.userId); if (sm != null) { for (int i = sm.mServicesByName.size()-1; i >= 0; i--) { ServiceRecord other = sm.mServicesByName.valueAt(i); @@ -1088,7 +1088,7 @@ public final class ActiveServices { requestServiceBindingLocked(s, b.intent, callerFg, false); } - getServiceMap(s.userId).ensureNotStartingBackground(s); + getServiceMapLocked(s.userId).ensureNotStartingBackgroundLocked(s); } finally { Binder.restoreCallingIdentity(origId); @@ -1230,7 +1230,7 @@ public final class ActiveServices { private final ServiceRecord findServiceLocked(ComponentName name, IBinder token, int userId) { - ServiceRecord r = getServiceByName(name, userId); + ServiceRecord r = getServiceByNameLocked(name, userId); return r == token ? r : null; } @@ -1268,7 +1268,7 @@ public final class ActiveServices { userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false, ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE, "service", null); - ServiceMap smap = getServiceMap(userId); + ServiceMap smap = getServiceMapLocked(userId); final ComponentName comp = service.getComponent(); if (comp != null) { r = smap.mServicesByName.get(comp); @@ -1335,7 +1335,7 @@ public final class ActiveServices { sInfo.name, sInfo.flags) && mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) { userId = 0; - smap = getServiceMap(0); + smap = getServiceMapLocked(0); } sInfo = new ServiceInfo(sInfo); sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId); @@ -1470,8 +1470,7 @@ public final class ActiveServices { return true; } - private final boolean scheduleServiceRestartLocked(ServiceRecord r, - boolean allowCancel) { + private final boolean scheduleServiceRestartLocked(ServiceRecord r, boolean allowCancel) { boolean canceled = false; if (mAm.isShuttingDownLocked()) { @@ -1480,7 +1479,7 @@ public final class ActiveServices { return false; } - ServiceMap smap = getServiceMap(r.userId); + ServiceMap smap = getServiceMapLocked(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 @@ -1594,7 +1593,7 @@ public final class ActiveServices { if (!mRestartingServices.contains(r)) { return; } - if (!isServiceNeeded(r, false, false)) { + if (!isServiceNeededLocked(r, false, false)) { // Paranoia: is this service actually needed? In theory a service that is not // needed should never remain on the restart list. In practice... well, there // have been bugs where this happens, and bad things happen because the process @@ -1676,7 +1675,7 @@ public final class ActiveServices { // Make sure this service is no longer considered delayed, we are starting it now. if (r.delayed) { if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (bring up): " + r); - getServiceMap(r.userId).mDelayedStartList.remove(r); + getServiceMapLocked(r.userId).mDelayedStartList.remove(r); r.delayed = false; } @@ -1858,7 +1857,7 @@ public final class ActiveServices { if (r.delayed) { if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (new proc): " + r); - getServiceMap(r.userId).mDelayedStartList.remove(r); + getServiceMapLocked(r.userId).mDelayedStartList.remove(r); r.delayed = false; } @@ -1939,7 +1938,8 @@ public final class ActiveServices { } } - private final boolean isServiceNeeded(ServiceRecord r, boolean knowConn, boolean hasConn) { + private final boolean isServiceNeededLocked(ServiceRecord r, boolean knowConn, + boolean hasConn) { // Are we still explicitly being asked to run? if (r.startRequested) { return true; @@ -1961,7 +1961,7 @@ public final class ActiveServices { //Slog.i(TAG, "Bring down service:"); //r.dump(" "); - if (isServiceNeeded(r, knowConn, hasConn)) { + if (isServiceNeededLocked(r, knowConn, hasConn)) { return; } @@ -2025,7 +2025,7 @@ public final class ActiveServices { r.userId, System.identityHashCode(r), (r.app != null) ? r.app.pid : -1); } - final ServiceMap smap = getServiceMap(r.userId); + final ServiceMap smap = getServiceMapLocked(r.userId); smap.mServicesByName.remove(r.name); smap.mServicesByIntent.remove(r.intent); r.totalRestartCount = 0; @@ -2097,7 +2097,7 @@ public final class ActiveServices { } } - smap.ensureNotStartingBackground(r); + smap.ensureNotStartingBackgroundLocked(r); } void removeConnectionLocked( @@ -2359,7 +2359,7 @@ public final class ActiveServices { mAm.mProcessStats); realStartServiceLocked(sr, proc, sr.createdFromFg); didSomething = true; - if (!isServiceNeeded(sr, false, false)) { + if (!isServiceNeededLocked(sr, false, false)) { // We were waiting for this service to start, but it is actually no // longer needed. This could happen because bringDownServiceIfNeeded // won't bring down a service that is pending... so now the pending @@ -2480,7 +2480,7 @@ public final class ActiveServices { void cleanUpRemovedTaskLocked(TaskRecord tr, ComponentName component, Intent baseIntent) { ArrayList<ServiceRecord> services = new ArrayList<>(); - ArrayMap<ComponentName, ServiceRecord> alls = getServices(tr.userId); + ArrayMap<ComponentName, ServiceRecord> alls = getServicesLocked(tr.userId); for (int i = alls.size() - 1; i >= 0; i--) { ServiceRecord sr = alls.valueAt(i); if (sr.packageName.equals(component.getPackageName())) { @@ -2612,7 +2612,7 @@ public final class ActiveServices { } } - ServiceMap smap = getServiceMap(app.userId); + ServiceMap smap = getServiceMapLocked(app.userId); // Now do remaining service cleanup. for (int i=app.services.size()-1; i>=0; i--) { @@ -2747,8 +2747,7 @@ public final class ActiveServices { return info; } - List<ActivityManager.RunningServiceInfo> getRunningServiceInfoLocked(int maxNum, - int flags) { + List<ActivityManager.RunningServiceInfo> getRunningServiceInfoLocked(int maxNum, int flags) { ArrayList<ActivityManager.RunningServiceInfo> res = new ArrayList<ActivityManager.RunningServiceInfo>(); @@ -2760,7 +2759,7 @@ public final class ActiveServices { uid) == PackageManager.PERMISSION_GRANTED) { int[] users = mAm.mUserController.getUsers(); for (int ui=0; ui<users.length && res.size() < maxNum; ui++) { - ArrayMap<ComponentName, ServiceRecord> alls = getServices(users[ui]); + ArrayMap<ComponentName, ServiceRecord> alls = getServicesLocked(users[ui]); for (int i=0; i<alls.size() && res.size() < maxNum; i++) { ServiceRecord sr = alls.valueAt(i); res.add(makeRunningServiceInfoLocked(sr)); @@ -2776,7 +2775,7 @@ public final class ActiveServices { } } else { int userId = UserHandle.getUserId(uid); - ArrayMap<ComponentName, ServiceRecord> alls = getServices(userId); + ArrayMap<ComponentName, ServiceRecord> alls = getServicesLocked(userId); for (int i=0; i<alls.size() && res.size() < maxNum; i++) { ServiceRecord sr = alls.valueAt(i); res.add(makeRunningServiceInfoLocked(sr)); @@ -2801,7 +2800,7 @@ public final class ActiveServices { public PendingIntent getRunningServiceControlPanelLocked(ComponentName name) { int userId = UserHandle.getUserId(Binder.getCallingUid()); - ServiceRecord r = getServiceByName(name, userId); + ServiceRecord r = getServiceByNameLocked(name, userId); if (r != null) { for (int conni=r.connections.size()-1; conni>=0; conni--) { ArrayList<ConnectionRecord> conn = r.connections.valueAt(conni); @@ -2874,31 +2873,6 @@ public final class ActiveServices { proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT)); } - /** - * Prints a list of ServiceRecords (dumpsys activity services) - */ - List<ServiceRecord> collectServicesToDumpLocked(ItemMatcher matcher, String dumpPackage) { - final ArrayList<ServiceRecord> services = new ArrayList<>(); - final int[] users = mAm.mUserController.getUsers(); - for (int user : users) { - ServiceMap smap = getServiceMap(user); - if (smap.mServicesByName.size() > 0) { - for (int si=0; si<smap.mServicesByName.size(); si++) { - ServiceRecord r = smap.mServicesByName.valueAt(si); - if (!matcher.match(r, r.name)) { - continue; - } - if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) { - continue; - } - services.add(r); - } - } - } - - return services; - } - final class ServiceDumper { private final FileDescriptor fd; private final PrintWriter pw; @@ -2932,7 +2906,7 @@ public final class ActiveServices { final int[] users = mAm.mUserController.getUsers(); for (int user : users) { - ServiceMap smap = getServiceMap(user); + ServiceMap smap = getServiceMapLocked(user); if (smap.mServicesByName.size() > 0) { for (int si=0; si<smap.mServicesByName.size(); si++) { ServiceRecord r = smap.mServicesByName.valueAt(si); @@ -3113,7 +3087,7 @@ public final class ActiveServices { } private void dumpUserRemainsLocked(int user) { - ServiceMap smap = getServiceMap(user); + ServiceMap smap = getServiceMapLocked(user); printed = false; for (int si=0, SN=smap.mDelayedStartList.size(); si<SN; si++) { ServiceRecord r = smap.mDelayedStartList.get(si); diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index 6b3be7a03fcd..3b4b8d620a2d 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -434,7 +434,7 @@ public final class BroadcastQueue { // but are on a queue that would like to wait for services to finish before moving // on. If there are background services currently starting, then we will go into a // special state where we hold off on continuing this broadcast until they are done. - if (mService.mServices.hasBackgroundServices(r.userId)) { + if (mService.mServices.hasBackgroundServicesLocked(r.userId)) { Slog.i(TAG, "Delay finish: " + r.curComponent.flattenToShortString()); r.state = BroadcastRecord.WAITING_SERVICES; return false; |