Fix issue #5253941: ICS ignoring provider's android:process flag
Provider was not being removed from the class map because it was using
the wrong key. D'oh.
Also a little cleanup.
Change-Id: I318e8b1a265318ac1474e0a7f14f27f89f357505
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 41af137..ed960d6 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1631,8 +1631,8 @@
}
if (app.conProviders.size() > 0) {
for (ContentProviderRecord cpr : app.conProviders.keySet()) {
- if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
- updateLruProcessInternalLocked(cpr.app, oomAdj,
+ if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
+ updateLruProcessInternalLocked(cpr.proc, oomAdj,
updateActivityTime, i+1);
}
}
@@ -3373,7 +3373,24 @@
for (i=0; i<N; i++) {
bringDownServiceLocked(services.get(i), true);
}
-
+
+ ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
+ for (ContentProviderRecord provider : mProvidersByClass.values()) {
+ if (provider.info.packageName.equals(name)
+ && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
+ if (!doit) {
+ return true;
+ }
+ didSomething = true;
+ providers.add(provider);
+ }
+ }
+
+ N = providers.size();
+ for (i=0; i<N; i++) {
+ removeDyingProviderLocked(null, providers.get(i));
+ }
+
if (doit) {
if (purgeCache) {
AttributeCache ac = AttributeCache.instance();
@@ -5485,7 +5502,7 @@
ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
ContentProviderRecord cpr = mProvidersByClass.get(comp);
if (cpr == null) {
- cpr = new ContentProviderRecord(cpi, app.info);
+ cpr = new ContentProviderRecord(cpi, app.info, comp);
mProvidersByClass.put(comp, cpr);
}
app.pubProviders.put(cpi.name, cpr);
@@ -5643,25 +5660,25 @@
// return it right away.
final boolean countChanged = incProviderCount(r, cpr);
if (countChanged) {
- if (cpr.app != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
+ if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
// If this is a perceptible app accessing the provider,
// make sure to count it as being accessed and thus
// back up on the LRU list. This is good because
// content providers are often expensive to start.
- updateLruProcessLocked(cpr.app, false, true);
+ updateLruProcessLocked(cpr.proc, false, true);
}
}
- if (cpr.app != null) {
+ if (cpr.proc != null) {
if (false) {
if (cpr.name.flattenToShortString().equals(
"com.android.providers.calendar/.CalendarProvider2")) {
Slog.v(TAG, "****************** KILLING "
+ cpr.name.flattenToShortString());
- Process.killProcess(cpr.app.pid);
+ Process.killProcess(cpr.proc.pid);
}
}
- boolean success = updateOomAdjLocked(cpr.app);
+ boolean success = updateOomAdjLocked(cpr.proc);
if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
// NOTE: there is still a race here where a signal could be
// pending on the process even though we managed to update its
@@ -5676,7 +5693,7 @@
"Existing provider " + cpr.name.flattenToShortString()
+ " is crashing; detaching " + r);
boolean lastRef = decProviderCount(r, cpr);
- appDiedLocked(cpr.app, cpr.app.pid, cpr.app.thread);
+ appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
if (!lastRef) {
// This wasn't the last ref our process had on
// the provider... we have now been killed, bail.
@@ -5729,7 +5746,7 @@
+ cpi.name);
return null;
}
- cpr = new ContentProviderRecord(cpi, ai);
+ cpr = new ContentProviderRecord(cpi, ai, comp);
} catch (RemoteException ex) {
// pm is in same process, this will never happen.
}
@@ -5864,7 +5881,7 @@
//update content provider record entry info
ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
ContentProviderRecord localCpr = mProvidersByClass.get(comp);
- if (localCpr.app == r) {
+ if (localCpr.proc == r) {
//should not happen. taken care of as a local provider
Slog.w(TAG, "removeContentProvider called on local provider: "
+ cpr.info.name + " in process " + r.processName);
@@ -5940,7 +5957,7 @@
}
synchronized (dst) {
dst.provider = src.provider;
- dst.app = r;
+ dst.proc = r;
dst.notifyAll();
}
updateOomAdjLocked(r);
@@ -8706,9 +8723,9 @@
r.dump(pw, " ");
} else {
pw.print(" * "); pw.print(e.getKey().flattenToShortString());
- if (r.app != null) {
+ if (r.proc != null) {
pw.println(":");
- pw.print(" "); pw.println(r.app);
+ pw.print(" "); pw.println(r.proc);
} else {
pw.println();
}
@@ -9440,7 +9457,7 @@
cpr.notifyAll();
}
- mProvidersByClass.remove(cpr.info.name);
+ mProvidersByClass.remove(cpr.name);
String names[] = cpr.info.authority.split(";");
for (int j = 0; j < names.length; j++) {
mProvidersByName.remove(names[j]);
@@ -9454,9 +9471,10 @@
&& capp.pid != MY_PID) {
Slog.i(TAG, "Kill " + capp.processName
+ " (pid " + capp.pid + "): provider " + cpr.info.name
- + " in dying process " + proc.processName);
+ + " in dying process " + (proc != null ? proc.processName : "??"));
EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
- capp.processName, capp.setAdj, "dying provider " + proc.processName);
+ capp.processName, capp.setAdj, "dying provider "
+ + cpr.name.toShortString());
Process.killProcessQuiet(capp.pid);
}
}
@@ -9515,7 +9533,7 @@
while (it.hasNext()) {
ContentProviderRecord cpr = it.next();
cpr.provider = null;
- cpr.app = null;
+ cpr.proc = null;
// See if someone is waiting for this provider... in which
// case we don't remove it, but just let it restart.