summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server/am/ActivityManagerService.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/java/com/android/server/am/ActivityManagerService.java')
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java73
1 files changed, 47 insertions, 26 deletions
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 9d5caae..7852123 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -5754,7 +5754,7 @@ public final class ActivityManagerService extends ActivityManagerNative
ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
if (cpr == null) {
- cpr = new ContentProviderRecord(cpi, app.info, comp);
+ cpr = new ContentProviderRecord(this, cpi, app.info, comp);
mProviderMap.putProviderByClass(comp, cpr);
}
if (DEBUG_MU)
@@ -5826,7 +5826,8 @@ public final class ActivityManagerService extends ActivityManagerNative
return msg;
}
- boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
+ boolean incProviderCount(ProcessRecord r, final ContentProviderRecord cpr,
+ IBinder externalProcessToken) {
if (r != null) {
Integer cnt = r.conProviders.get(cpr);
if (DEBUG_PROVIDER) Slog.v(TAG,
@@ -5842,12 +5843,13 @@ public final class ActivityManagerService extends ActivityManagerNative
r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
}
} else {
- cpr.externals++;
+ cpr.addExternalProcessHandleLocked(externalProcessToken);
}
return false;
}
- boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
+ boolean decProviderCount(ProcessRecord r, final ContentProviderRecord cpr,
+ IBinder externalProcessToken) {
if (r != null) {
Integer cnt = r.conProviders.get(cpr);
if (DEBUG_PROVIDER) Slog.v(TAG,
@@ -5863,13 +5865,13 @@ public final class ActivityManagerService extends ActivityManagerNative
r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
}
} else {
- cpr.externals++;
+ cpr.removeExternalProcessHandleLocked(externalProcessToken);
}
return false;
}
private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
- String name) {
+ String name, IBinder token) {
ContentProviderRecord cpr;
ProviderInfo cpi = null;
@@ -5913,7 +5915,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// In this case the provider instance already exists, so we can
// return it right away.
- final boolean countChanged = incProviderCount(r, cpr);
+ final boolean countChanged = incProviderCount(r, cpr, token);
if (countChanged) {
if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
// If this is a perceptible app accessing the provider,
@@ -5947,7 +5949,7 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.i(TAG,
"Existing provider " + cpr.name.flattenToShortString()
+ " is crashing; detaching " + r);
- boolean lastRef = decProviderCount(r, cpr);
+ boolean lastRef = decProviderCount(r, cpr, token);
appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
if (!lastRef) {
// This wasn't the last ref our process had on
@@ -6005,7 +6007,7 @@ public final class ActivityManagerService extends ActivityManagerNative
return null;
}
ai = getAppInfoForUser(ai, Binder.getOrigCallingUser());
- cpr = new ContentProviderRecord(cpi, ai, comp);
+ cpr = new ContentProviderRecord(this, cpi, ai, comp);
} catch (RemoteException ex) {
// pm is in same process, this will never happen.
}
@@ -6075,8 +6077,9 @@ public final class ActivityManagerService extends ActivityManagerNative
if (firstClass) {
mProviderMap.putProviderByClass(comp, cpr);
}
+
mProviderMap.putProviderByName(name, cpr);
- incProviderCount(r, cpr);
+ incProviderCount(r, cpr, token);
}
}
@@ -6116,12 +6119,17 @@ public final class ActivityManagerService extends ActivityManagerNative
throw new SecurityException(msg);
}
- ContentProviderHolder contentProvider = getContentProviderImpl(caller, name);
- return contentProvider;
+ return getContentProviderImpl(caller, name, null);
+ }
+
+ public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
+ enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
+ "Do not have permission in call getContentProviderExternal()");
+ return getContentProviderExternalUnchecked(name, token);
}
- private ContentProviderHolder getContentProviderExternal(String name) {
- return getContentProviderImpl(null, name);
+ private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
+ return getContentProviderImpl(null, name, token);
}
/**
@@ -6157,14 +6165,20 @@ public final class ActivityManagerService extends ActivityManagerNative
+ cpr.info.name + " in process " + r.processName);
return;
} else {
- if (decProviderCount(r, localCpr)) {
+ if (decProviderCount(r, localCpr, null)) {
updateOomAdjLocked();
}
}
}
}
- private void removeContentProviderExternal(String name) {
+ public void removeContentProviderExternal(String name, IBinder token) {
+ enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
+ "Do not have permission in call removeContentProviderExternal()");
+ removeContentProviderExternalUnchecked(name, token);
+ }
+
+ private void removeContentProviderExternalUnchecked(String name, IBinder token) {
synchronized (this) {
ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
Binder.getOrigCallingUser());
@@ -6178,11 +6192,18 @@ public final class ActivityManagerService extends ActivityManagerNative
ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
Binder.getOrigCallingUser());
- localCpr.externals--;
- if (localCpr.externals < 0) {
- Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
+ if (localCpr.hasExternalProcessHandles()) {
+ if (localCpr.removeExternalProcessHandleLocked(token)) {
+ updateOomAdjLocked();
+ } else {
+ Slog.e(TAG, "Attmpt to remove content provider " + localCpr
+ + " with no external reference for token: "
+ + token + ".");
+ }
+ } else {
+ Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
+ + " with no external references.");
}
- updateOomAdjLocked();
}
}
@@ -6286,7 +6307,7 @@ public final class ActivityManagerService extends ActivityManagerNative
ContentProviderHolder holder = null;
try {
- holder = getContentProviderExternal(name);
+ holder = getContentProviderExternalUnchecked(name, null);
if (holder != null) {
return holder.provider.getType(uri);
}
@@ -6295,7 +6316,7 @@ public final class ActivityManagerService extends ActivityManagerNative
return null;
} finally {
if (holder != null) {
- removeContentProviderExternal(name);
+ removeContentProviderExternalUnchecked(name, null);
}
Binder.restoreCallingIdentity(ident);
}
@@ -6400,7 +6421,7 @@ public final class ActivityManagerService extends ActivityManagerNative
public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
enforceNotIsolatedCaller("openContentUri");
String name = uri.getAuthority();
- ContentProviderHolder cph = getContentProviderExternal(name);
+ ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
ParcelFileDescriptor pfd = null;
if (cph != null) {
// We record the binder invoker's uid in thread-local storage before
@@ -6422,7 +6443,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
// We've got the fd now, so we're done with the provider.
- removeContentProviderExternal(name);
+ removeContentProviderExternalUnchecked(name, null);
} else {
Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
}
@@ -10253,7 +10274,7 @@ public final class ActivityManagerService extends ActivityManagerNative
for (int i=0; i<NL; i++) {
ContentProviderRecord cpr = (ContentProviderRecord)
mLaunchingProviders.get(i);
- if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
+ if (cpr.clients.size() <= 0 && !cpr.hasExternalProcessHandles()) {
synchronized (cpr) {
cpr.launchingApp = null;
cpr.notifyAll();
@@ -13455,7 +13476,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// If the provider has external (non-framework) process
// dependencies, ensure that its adjustment is at least
// FOREGROUND_APP_ADJ.
- if (cpr.externals != 0) {
+ if (cpr.hasExternalProcessHandles()) {
if (adj > ProcessList.FOREGROUND_APP_ADJ) {
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = Process.THREAD_GROUP_DEFAULT;